Python - 入站出站参数
我在《Python 专家编程》中读到过有关这种边缘情况的内容。检查这段代码:
def f(arg={}):
arg['3'] = 4
return arg
>>> print f()
{'3': 4}
>>> res = f()
>>> res['4'] = 'Still here'
>>> print f()
{'3': 4, '4': 'Still here'}
我不清楚为什么最后一次调用 f
时(在保存其返回值之后),而不是将 arg 分配给空字典(因为它是在没有参数的情况下调用的) ,它保留旧的参考。
书中是这样说的:“如果在参数中创建了一个对象,那么如果函数返回该对象,参数引用仍然有效”。
我明白“事情就是这样”,但为什么会这样呢?
I've read in Expert Python Programming about this edge case. Check this code:
def f(arg={}):
arg['3'] = 4
return arg
>>> print f()
{'3': 4}
>>> res = f()
>>> res['4'] = 'Still here'
>>> print f()
{'3': 4, '4': 'Still here'}
It's not clear to me why when f
gets called the last time (after its return value has been saved), instead of assigning arg the empty dict (since it was called with no arguments), it keeps the old reference.
The book says so: "if an object is created within the arguments, the argument reference will still be alive if the function returns the object".
I understand that "this is the way it works", but why so?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因为默认参数仅在函数被求值和创建时求值一次(它们是函数定义的一部分,例如可以通过 inform.getargspec 获取)。
由于它们是函数的一部分,因此对函数的每次调用都将具有默认值的相同实例。如果它是一个不可变的值,这不是问题,但一旦它是可变的,它就会成为一个问题。
相同的“特征”存在于类定义中,给定一个类定义:
调用
... 将使 y.foo['bar'] 计算为“baz”,因为 x 和 y 具有相同富。
这就是为什么成员初始化应该在init而不是类体中完成。
Because the default arguments are evaluated once only, when the function is evaluated and created (they are part of the function defenition and can be fetched through inspect.getargspec, for example).
Since they are part of the function, every call to the function will have the same instance of the default value. This is not a problem if it is an immutable value, but as soon as it is mutable it can become a gotcha.
The same 'feature' exist in class defenitions, given a class defenition:
calling
...would give that y.foo['bar'] evaluates to "baz", since x and y has the same foo.
This is why member initialization should be done in init instead of the class body.
您的问题是默认为可变参数(在本例中为字典):
应该是:
yields:
就像您所期望的那样。
这里的问题是默认参数是在第一次定义/解析函数时计算的,而不是在调用它们时计算的。这只是您需要注意的 python 解析器的细微差别。
要了解原因,请查看“Least Astonishment”和可变默认参数< /a>
Your problem is defaulting to a mutable argument (dictionary in this case):
should be:
yields:
like you'd expect.
The issue here is the default arguments are evaluated when the function is first defined/parsed, not when they are called. It's just a nuance of the python parser that you need to be aware of.
For the why, check out "Least Astonishment" and the Mutable Default Argument
默认参数在声明函数时创建一次,因此每次调用 f() 都会获得相同的字典实例,该实例一开始为空。这能回答问题吗?
The default parameter gets created once, when the functon is declared, so every call to f() gets the same instance of a dictionary, which starts out empty. Does that answer the question?