>> >>> def b(x=a()): ... -6ren">
gpt4 book ai didi

不可变默认参数值的 Python 行为

转载 作者:太空宇宙 更新时间:2023-11-04 08:10:31 25 4
gpt4 key购买 nike

>>> def a():
... print "a executed"
... return []
...
>>>
>>> def b(x=a()):
... x.append(5)
... print x
...
a executed
>>> b()
[5]
>>> b()
[5, 5]

x 在第一次定义函数 b 时绑定(bind)到一个空列表对象。每次调用 b 时都会修改空列表对象,因为 b 已绑定(bind)到该对象。

我不明白的是,当这种情况发生在不可变对象(immutable对象)上时:

>>> def a():
... print "a executed"
... return 0
...
>>>
>>> def b(x=a()):
... x = x + 2
... print x
...
a executed
>>> b()
2
>>> b()
2

从我的 POV 来看,当第一次定义函数 b 时,x 绑定(bind)到 int 对象 0。然后,在调用 b() 时修改 x。因此,对 b() 的后续调用应将 x 重新绑定(bind)到 2、4、6 等。为什么不发生这种情况?我显然在这里遗漏了一些重要的东西!

谢谢 :)

最佳答案

当您执行 x = 时,您并没有修改 x 引用的对象,您只是将引用 x 更改为指向到不同的对象,在本例中是另一个 int。在这种情况下,x 是否指向不可变对象(immutable对象)与事件无关。如果您对列表执行 x = x + [5],它也将保持不变。注意区别:

def b1(x = []):
x = x + [5]
print(x)

def b2(x = []):
x.append(5)
print(x)

print("b1:")
b1()
print("b1:")
b1()

print("b2:")
b2()
print("b2:")
b2()

给予:

b1:
[5]
b1:
[5]
b2:
[5]
b2:
[5, 5]

当函数被执行时,您正在处理一个局部变量 x,它要么使用默认值初始化,要么由调用者提供。所以反弹的是局部变量x,而不是参数的默认值。

您可能还想了解正式实际 参数之间的区别。它与这个问题只有轻微的关系,但可能会帮助您更好地理解这一点。可以找到示例说明 here .

关于不可变默认参数值的 Python 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23397022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com