类定义代码块以及传给exec()和eval()的参数的作用域是特殊情况。
类定义是可能使用并定义名称(变量)的可执行语句。 这些引用遵循正常的名称解析规则,例外之处在于未绑定的局部变量将会在全局命名空间中查找。 类定义的命名空间会成为该类的属性字典。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# 变量对象a拥有全局作用域
a = "Hello"
class A:
# 实例方法调用在类内部未绑定的变量a
# 未绑定的变量a将会在全局命名空间中查找。值是Hello
def print_a(self):
print(a)
# 实例方法调用在类内部未绑定的变量b
# 未绑定的变量b将会在全局命名空间中查找。查找不到,抛出NameError异常
def print_b(self):
print(b)
# 类方法调用在类内部未绑定的变量a
@classmethod
def print_a_by_class(cls):
print(a)
aa = A()
aa.print_a() # 输出Hello
A.print_a_by_class() # 输出Hello
aa.print_b() # 全局空间也没有找到变量b,抛出NameError异常
|
执行以上程序会输出如下结果:
1
2
3
4
5
6
7
8
|
Hello
Hello
Traceback (most recent call last):
File "main.py", line 22, in <module>
aa.print_b()
File "main.py", line 12, in print_b
print(b)
NameError: name 'b' is not defined
|
在类代码块中定义的名称的作用域会被限制在类代码块中;它不会扩展到方法的代码块中 – 这也包括推导式和生成器表达式,因为它们都是使用函数作用域实现的。
例子1
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 变量对象a拥有全局作用域
a = "Hello"
class A:
# 变量对象a拥有类A的作用域,但是不能在类内部的方法print_a中使用。
a = "class var"
# 实例方法调用在类内部绑定的变量a
def print_a(self):
print(a)
aa = A()
aa.print_a() # 输出Hello,而不是class var
|
例子2,生成器表达式不能使用局部变量a,抛出NameError异常。
1
2
3
4
5
|
class A:
a = 42
b = list(a + i for i in range(10))
aa = A()
|
执行以上程序会输出如下结果:
1
2
3
4
5
6
7
8
|
Traceback (most recent call last):
File "main.py", line 1, in <module>
class A:
File "main.py", line 3, in A
b = list(a + i for i in range(10))
File "main.py", line 3, in <genexpr>
b = list(a + i for i in range(10))
NameError: name 'a' is not defined
|
例子3,推导式表达式不能使用局部变量a,抛出NameError异常。
1
2
3
4
5
|
class A:
a = 42
b = [a + i for i in range(10)]
aa = A()
|
执行以上程序会输出如下结果:
1
2
3
4
5
6
7
8
|
Traceback (most recent call last):
File "main.py", line 1, in <module>
class A:
File "main.py", line 3, in A
b = [a + i for i in range(10)]
File "main.py", line 3, in <listcomp>
b = [a + i for i in range(10)]
NameError: name 'a' is not defined
|
转载请注明本网址。