【问题标题】:Why static binding works differently for class and function?为什么静态绑定对类和函数的工作方式不同?
【发布时间】:2013-12-07 12:48:33
【问题描述】:

在 python 中(在 2.7.6 上测试)所有变量都是 在编译时静态绑定到作用域。这个过程很好 在http://www.python.org/dev/peps/pep-0227/http://docs.python.org/2.7/reference/executionmodel.html

明确指出“如果发生名称绑定操作 代码块内的任何地方,块内名称的所有使用 被视为对当前块的引用。”

函数是一个代码块,因此以下代码失败,因为x 在使用后分配(因此在编译时它被定义为本地 因为它被分配在函数的某个地方,但在执行时 时间,在绑定之前使用)。

x = 1
def f():
    print x 
    x = 2
    print x

>>> f()

Traceback (most recent call last):
  File "<pyshell#46>", line 1, in <module>
    f()
  File "<pyshell#45>", line 2, in f
    print x
UnboundLocalError: local variable 'x' referenced before assignment

一个类也是一个代码块,所以我们应该准确地观察 相同的行为。但这不是我观察到的。 看这个例子:

x = 1
class C():
    y = x + 10
    x = 2
    def __init__(self):
        print C.y

>>> C.x
2
>>> C.y
11      
>>> C()
11
<__main__.C instance at 0x00000000027CC9C8>

由于类定义是一个代码块,因此在此范围内的任何赋值 块应该使变量本地化。所以x 应该是本地的 类C,所以y = x + 10 应该导致UnboundLocalError。 为什么没有这样的错误?

【问题讨论】:

  • 这个线程stackoverflow.com/questions/12810426/… 指的是同一个问题,但没有给出强有力的解释。 PEP-0227 和 python 2.7 执行模型在功能块或类块之间没有任何区别
  • 这是一个常见的范围问题。请注意以下命名空间的区别:&lt;function f at 0x1092a80c8&gt;&lt;class __main__.C at 0x1092946d0&gt;。区别在于__main__ 命名空间。
  • 另外,这与stackoverflow.com/questions/12810426/…关系非常密切
  • @VooDooNOFX 我还是不明白你的解释。一个类是一个代码块,而在代码块的任何地方分配的变量都是局部的。这不是我观察到的。看起来只有函数的静态绑定,但我在 Python 文档中没有找到对此行为的任何引用。

标签: python class scope static-binding


【解决方案1】:

是的 - 文档似乎具有误导性。类定义实际上与其他普通块的工作方式不同:

global_one = 0

class A(object):
    x = global_one + 10
    global_one = 100
    y = global_one + 20
    del global_one
    z = global_one + 30

a = A()
print a.x, a.y, a.z, global_one

结果:10, 120, 30, 0

如果你用一个函数尝试同样的事情,你会在你第一次访问global_one时得到一个UnboundLocalError

这样做的原因是类定义通常可以访问父范围,但是,所有名称分配都不会修改本地范围,而是实际上被捕获到类的数据属性字典中。文档中有这方面的提示,但肯定不是很明显。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多