python tips - 注意函数参数的默认值
且看如下例子:
def f(a=[]): a.append(0) return a print dir(f) for i in range(3): print f() print f.__defaults__
结果:
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name'] ([],) [0] ([0],) [0, 0] ([0, 0],) [0, 0, 0]
函数参数的默认值会保存上次调用的修改么?
每运行一次,函数作为一个对象的内在属性的值发生了变化。导致每次运行的结果不一致
def f(num=0): num += 1 return num print dir(f) for i in range(3): print f.__defaults__ print f()
结果:
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name'] (0,) 1 (0,) 1 (0,) 1
函数参数的默认值怎么又没有保存上次调用的修改呢?
参考:python tips - Python可变对象和不可变对象:http://www.cnblogs.com/congbo/archive/2012/11/20/2777031.html
使用可变参数作为默认值可能导致意料之外的行为。为了防止出现这种情况,最好使用None值,并且在后面加上检查代码,如示例1改为:
def f(a=None): if a is None: a = [] a.append(0) return a
查阅Python manual有如下的说法:
Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that that same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function, e.g.:
python中函数的默认值只会被执行一次,(和静态变量一样,静态变量初始化也是被执行一次)。Python可以通过函数的默认值来实现静态变量的功能。