Python 函数调用范围大、有状态、无法初始化参数? [英] Python function calls are bleeding scope, stateful, failing to initialize parameters?
问题描述
在我敢于提交错误报告之前,我想我应该在更聪明的 Pythonistas 中检查我的假设.今天遇到一个莫名其妙的案例,所以我把它缩减为一个玩具示例,如下所示:
Before I have the audacity to file a bug report, I thought I'd check my assumptions among wiser Pythonistas here. I encountered a baffling case today, so I whittled it down to a toy example, shown below:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
A little script to demonstrate that a function won't re-initialize its
list parameters between calls, but instead allows them to retain state.
"""
def bleedscope(a=[], b=[]):
"""
On each call, unless explicitly passed, both `a` and `b` should be
initialized as empty lists.
"""
c = a
if b:
c.extend(b)
return len(c)
x = bleedscope(b=[1])
print x # Should be 1, as expected.
x = bleedscope(b=[2])
print x # Expect also to be 1, but it's 2. `a` is retained.
x = bleedscope(a=[1])
print x # Now 1 as expected.
x = bleedscope(b=[3])
print x # 1 as expected? No, it's 3! Insanity!
我认为函数参数在函数范围内是局部的,并且在函数调用结束时被垃圾收集,从不保留它们之间的状态.不过,我已经在 Python 2.5.2 和 Python 2.6.1 上测试了上述脚本,但我的理解并不是结果.参数 a
肯定会在大多数这些调用之间保留状态;最令人困惑的是对 bleedscope
的最后一次调用,它跳过前一个调用的状态并返回到第二个结束时的状态(即 [1, 2]
).[我建议在您最喜欢的调试器中运行它,以亲自查看.如果你没有,我建议 Winpdb 作为一个可靠的 FOSS 独立 Python 调试器.]
I thought function arguments were local in scope to the function, and were garbage-collected at the end of a function call, never to retain state between them. I have tested the above script on Python 2.5.2 and Python 2.6.1, though, and my understanding does not the results. Argument a
certainly retains state between most of these calls; the most perplexing one being the final call to bleedscope
, where it skips the state of the previous call and goes back to the state at the end of the second (i.e., [1, 2]
). [I suggest running this in your favorite debugger to see for yourself. If you don't have one, I suggest Winpdb as a solid FOSS standalone Python debugger.]
这是怎么回事?
推荐答案
在 Python 中,只有在解析 def 调用时才会初始化默认参数值.对于对象(例如您的列表),它会在调用之间重复使用.看看这篇关于它的文章,它也提供了必要的解决方法:
In Python default parameter values only get initialized when the def call is parsed. In the case of an object (such as your lists), it gets reused between calls. Take a look at this article about it, which also provides the necessary workaround:
http://effbot.org/zone/default-values.htm
这篇关于Python 函数调用范围大、有状态、无法初始化参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!