为什么静态绑定对类和函数的工作方式不同?

时间:2013-11-22 15:17:11

标签: python class scope static-binding

在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。 为什么没有这样的错误?

1 个答案:

答案 0 :(得分:3)

是的 - 文档似乎有误导性。类定义实际上与其他普通块完全不同:

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

如果您使用某个功能尝试相同的操作,则首次访问UnboundLocalError时会收到global_one

原因是普通的类定义可以访问父作用域,但是,所有名称赋值都不会修改本地作用域,但实际上会捕获到类的数据属性字典中。文档中有关于此的提示,但肯定不是很明显。