Python 函数调用范围大、有状态、无法初始化参数? [英] Python function calls are bleeding scope, stateful, failing to initialize parameters?

查看:53
本文介绍了Python 函数调用范围大、有状态、无法初始化参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我敢于提交错误报告之前,我想我应该在更聪明的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆