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可以通过函数的默认值来实现静态变量的功能。

posted @ 2012-11-29 13:31  congbo  阅读(2452)  评论(0编辑  收藏  举报