这个消息有点长,有很多例子,但我希望它能帮助我和其他人更好地掌握Python 2.7中变量和属性查找的全部故事.
我正在使用PEP 227(http://www.python.org/dev/peps/pep-0227/)的条款来代码块(例如模块,类定义,函数定义等)和变量绑定(例如作为赋值,参数声明,类和函数声明,for循环等)
我使用的术语变量,可以在不点叫名字,并需要与对象名称限定(如obj.x的属性x对象obj的)名称属性.
Python中有三个范围用于所有代码块,但功能如下:
Python中只有四个块用于函数(根据PEP 227):
变量绑定到块并在块中找到它的规则非常简单:
让我知道验证这条规则的例子,并展示许多特殊情况.对于每个例子,我都会给出我的理解.如果我错了,请纠正我.对于最后一个例子,我不明白结果.
例1:
x = "x in module"
class A():
print "A: " + x #x in module
x = "x in class A"
print locals()
class B():
print "B: " + x #x in module
x = "x in class B"
print locals()
def f(self):
print "f: " + x #x in module
self.x = "self.x in f"
print …Run Code Online (Sandbox Code Playgroud) 在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
Run Code Online (Sandbox Code Playgroud)
类也是代码块,因此我们应该观察到完全相同的行为.但这不是我观察到的.看看这个例子:
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 …Run Code Online (Sandbox Code Playgroud)