关于Pyhton默认参数的一些思考

作者: SHISHENGJIA | 来源:发表于2017-05-22 16:07 被阅读22次

我们知道Python中函数的可选参数可以有默认值,但是该默认值不能是可变类型。下面以一个简单的例子简单说明一下。

class HauntedBus:
    """闹鬼的校车"""

    def __init__(self, passengers=[]):
        self.passengers = passengers

    def pick(self, name):
        """上车"""
        self.passengers.append(name)

    def drop(self, name):
        """下车"""
        self.passengers.remove(name)

bus1 = HauntedBus()
bus1.pick('Tom')
print(bus1.passengers)  # ['Tom']

bus2 = HauntedBus()  # ['Tom']
print(bus2.passengers)

bus2.pick('Jack')
print(bus2.passengers)  # ['Tom', 'Jack']

print(bus1.passengers is bus2.passengers)  # True

从结果中可以看出,登上bus1的乘客Tom出现在了bus2中。
问题在于,没有指定初始乘客的 HauntedBus 实例会共享同一个乘客列表。
这是因为不为 HauntedBus 指定乘客的话self.passengers 变成了 passengers 参数默认值(即[])的别名,而这个问题的根源在于默认值在定义函数时计算(通常在加载模块时),就已经变成了函数对象的属性。因此,如果默认值是可变对象,而且修改了它的值,那么后续的函数调用都会受到影响。
可变默认值导致的这个问题说明了为什么通常使用 None 作为接收可变值的参数的默认值。
下面修改上面例子中的部分问题代码。

def __init__(self, passengers=None):
    if passengers is None:
        self.passengers = []
    else:
        self.passengers = list(passengers)

在这个代码中,如果构造实例时没有传入参数,那么会新建一个空列表赋值给self.passengers,另外值得注意的是,如果参数passengers不为None,我们将参数值的副本list(passengers)赋值给了self.passengers。这是因为如果直接将passengers赋值给self.passengers的话,那么在self.passengers上直接调用remove()或者append()方法的话,其实会修改传给构造方法的那个列表。

相关文章

  • 关于Pyhton默认参数的一些思考

    我们知道Python中函数的可选参数可以有默认值,但是该默认值不能是可变类型。下面以一个简单的例子简单说明一下。 ...

  • python学习(五)-函数的参数

    默认参数 设置默认参数时,有几点要注意: 一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下...

  • Mac install python3 同时安装2.7和3.7

    Mac默认有pyhton 2.7版本 我发现默认有2.7,然后我想要python 3, 看了一些文章都是到官网下载...

  • 20.11.10 python函数参数与argparse命令行解

    Pyhton函数参数 python总共有4中参数类型:定位参数(positional argument, 也有叫必...

  • python中,定义函数默认值,要注意的几点

    一是,必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);二...

  • 关于默认参数的坑

    情景:按时间筛选 mongodb 查询结果,两个参数start_timeandend_time,如果不传这两个参数...

  • 关于python的默认参数

    首先从函数的定义开始理解****命题1: ****函数的定义不会引起函数内部代码的执行 看下面这个函数, 函数内部...

  • 3、函数的默认参数

    今天的内容是关于函数的默认参数。首先我们写一个带有默认参数的函数: 然后我们有三种方式进行调用: 注意,带默认参数...

  • iview控件绑定事件的时候,传递多个参数

    iview控件有时候使用的时候,默认不写就会绑定默认参数,但是有时候除了默认参数外,还想传递一些自己自定义的参数,...

  • Function

    默认参数 对于函数而言,经常会用到参数,关于参数的默认值通常都是写在函数体中,如在 ES5 写法 当一个函数有很多...

网友评论

    本文标题:关于Pyhton默认参数的一些思考

    本文链接:https://www.haomeiwen.com/subject/razbxxtx.html