在我大胆地提交错误报告之前,我想我会在这里用更聪明的Pythonistas检查我的假设.我今天遇到了一个令人困惑的案例,所以我把它改成了一个玩具示例,如下所示:
#!/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!
Run Code Online (Sandbox Code Playgroud)
我认为函数参数在函数范围内是局部的,并且在函数调用结束时被垃圾收集,永远不会在它们之间保留状态.我已经在Python 2.5.2和Python 2.6.1上测试了上面的脚本,但我的理解不是结果.争论a当然保留了大多数这些电话之间的状态; 最令人困惑的是最后一次呼叫bleedscope,它跳过前一个呼叫的状态,然后返回到第二个呼叫的状态(即,[1, 2]).[我建议在你最喜欢的调试器中运行它来亲眼看看.如果你没有,我建议将Winpdb作为一个可靠的FOSS独立Python调试器.]
这里发生了什么?
Kai*_*Kai 15
在Python中,默认参数值仅在解析def调用时初始化.对于对象(例如列表),它会在调用之间重用.看看这篇关于它的文章,它也提供了必要的解决方法:
http://effbot.org/zone/default-values.htm
这是你的问题:
def bleedscope(a=[], b=[]):
Run Code Online (Sandbox Code Playgroud)
它应该是
def bleedscope(a=None, b=None):
if a is None: a = []
if b is None: b = []
Run Code Online (Sandbox Code Playgroud)
默认参数仅在解析函数时执行一次,因此每次使用相同的2个列表.
| 归档时间: |
|
| 查看次数: |
935 次 |
| 最近记录: |