在定义python函数的默认参数时,为什么使用不可变对象就可以避免可变对象带来的问题?

def test(def_arg=None):
    if def_arg == None:
        def_arg = []
    def_arg.append(1)
    return def_arg

test()
test()

第一次调用test函数时,def_arg在函数定义时已被赋值为None值,所以def_arg被绑定到一个列表对象,然后增加了一个item。

第二次调用test函数时,def_arg的值为什么仍然是None而不是[1]呢?

阅读 2.5k
3 个回答
def add_end(L=[]):
    L.append('END')
    return L

Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。

def test(def_arg=None):

None 是默认参数,def_arg 不是。

所以改变 def_arg 不会改变默认参数,但是改变 None 会。但是 None 是不可变的,所以默认参数永远变不了。

但是

def test(def_arg=[]):

def_arg.append 会改变默认参数 [] 。所以再次调用时默认参数会变。

_

例子:

def f(n,ls=5):
    ls +=1
    return n+ls
print(f(1))        #7
print(f(2))        #8

会不会是形参的缺省参数属于f的对象,随着f存在而存在,而ls += 1是函数调用时存在的变量空间里头临时绑定的,就是这个ls和形参ls不是一个东西呗?(一个在f.__defaults__内,一个在调用临时产生的变量空间内)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题