这个消息是有点长有很多例子,但我希望它
将帮助我和其他人更好地掌握变量的全部故事
和属性查找在Python 2.7。
我使用的是PEP 227的条款
(http://www.python.org/dev/peps/pep-0227/)代码块(例如
模块,类定义,函数定义等)和
变量绑定(如赋值,变量声明,类
和函数声明,for循环等)
我使用术语变量名称可以调用没有
点和属性,用于需要使用对象限定的名称
名称(例如对象obj的属性x的obj.x)。
Python中有三个范围用于所有代码块,但功能如下:
>本地
>全球
>内置
Python中有四个块仅用于函数(根据
PEP 227):
>本地
>封闭函数
>全球
>内置
变量绑定到和在块中找到它的规则是
非常简单:
>任何将变量绑定到块中的对象使这个变量
局部到这个块,除非变量被声明为全局变量
case该变量属于全局范围)
>对变量的引用使用规则LGB(local,
全局,内置)为所有块,但功能
>使用规则LEGB(local,
包含,全局,内置)。
让我知道采取例子验证这条规则,并显示许多
特殊情况。对于每个例子,我会给我的理解。请
纠正我,如果我错了。对于最后一个例子,我不明白
结果。
示例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 x, self.x
print locals()
>>>A.B().f()
A: x in module
{'x': 'x in class A', '__module__': '__main__'}
B: x in module
{'x': 'x in class B', '__module__': '__main__'}
f: x in module
x in module self.x in f
{'self': <__main__.b instance at>}
没有类(规则LGB)和函数in的嵌套作用域
类不能访问类的属性,而不使用
限定名(本例中为self.x)。这在中有详细描述
PEP227。
示例2:
z = "z in module"
def f():
z = "z in f()"
class C():
z = "z in C"
def g(self):
print z
print C.z
C().g()
f()
>>>
z in f()
z in C
这里使用LEGB规则查找函数中的变量,但是如果
一个类在路径中,类参数被跳过。又是在这里,
这是PEP 227解释的。
示例3:
var = 0
def func():
print var
var = 1
>>> func()
Traceback (most recent call last):
File "", line 1, in
func()
File "C:/Users/aa/Desktop/test2.py", line 25, in func
print var
UnboundLocalError: local variable 'var' referenced before assignment
我们期望一个动态语言,如python,一切都是
动态解析。但是这不是函数的情况。本地
变量在编译时确定。 PEP 227和
http://docs.python.org/2.7/reference/executionmodel.html描述这一点
行为这种方式
“如果一个名称绑定操作发生在代码块中的任何地方,所有
在块内的名称的使用被视为对的引用
当前块“。
示例4:
x = "x in module"
class A():
print "A: " + x
x = "x in A"
print "A: " + x
print locals()
del x
print locals()
print "A: " + x
>>>
A: x in module
A: x in A
{'x': 'x in A', '__module__': '__main__'}
{'__module__': '__main__'}
A: x in module
但是我们在这里看到这个语句在PEP227“如果一个名字绑定
操作发生在代码块内的任何地方,所有使用的名称
在块内被视为对当前块的引用
当代码块是一个类时出错。此外,对于类,似乎
该局部名称绑定不是在编译时,而是在期间
执行使用类命名空间。在这方面,
PEP227和Python文档中的执行模型具有误导性
有些部分错了。
示例5:
x = 'x in module'
def f2():
x = 'x in f2'
def myfunc():
x = 'x in myfunc'
class MyClass(object):
x = x
print x
return MyClass
myfunc()
f2()
>>>
x in module
我对这段代码的理解如下。指令x = x
首先查找对象的右手x的表达式是指
至。在这种情况下,在本地查找对象,然后
遵循规则LGB它在全局范围中查找,即
字符串’x in module’。然后一个局部属性x到MyClass
在类字典中创建并指向字符串对象。
示例6:
现在这里是一个例子,我不能解释。
它非常接近示例5,我只是更改本地MyClass
属性从x到y。
x = 'x in module'
def f2():
x = 'x in f2'
def myfunc():
x = 'x in myfunc'
class MyClass(object):
y = x
print y
return MyClass
myfunc()
f2()
>>>
x in myfunc
为什么在这种情况下在MyClass中的x引用在中查找
最内层函数?