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

你可能感兴趣的:(python)