为了在我的代码中获得一些顺序,我将一个类放在另一个类中,内部类根本不需要外部类(至少这是我之前想到的)。
代码行为:
class A:
def __init__(self):
self.a=10
def do(self):
print(self.a)
return A()
a=A()
print(a.do())
#this runs as expected with the output:
#10
#<__main__.A object at 0x01234567>
#cleaning up
del A
class B:
#same code for class A
class A:
def __init__(self):
self.a=10
def do(self):
print(self.a)
return A()
a=B.A()
print(a.do())
#This raises for the line 'return A()' a NameError: global name 'A' is not defined
我无法理解为什么在这种情况下A无法从内部访问。
这是另一件类似且运行正常的事情:
def f():
a=10
class C:
def __init__(self):
pass
def do(self):
print(a)
return C()
return C().do()
print(f())
附加问题:在这种情况下,为什么班级的行为与行为不同,我们从中获得的好处是什么?
答案 0 :(得分:1)
你应该用这个:
return B.A()
由于类A
不是全局变量,因此它是类B
的属性。类本身就是名称空间,即在类中定义的所有对象实际上都成为它的属性。
class B:
#same code for class A
class A:
def __init__(self):
self.a=10
def do(self):
print(self.a)
return B.A()
>>> B.A
<class __main__.A at 0x9f3ea1c>
>>> a = B.A()
>>> print(a.do())
10
<__main__.A instance at 0x9fd7aec>
代码2:
def f():
a=10
class C:
def __init__(self):
pass
def do(self):
print(a)
return C()
return C().do()
print(f())
这个代码与嵌套的第一类完全不同。函数不会创建新的命名空间,只是创建一个新的范围。
因此,类C
只是一个用于f()
的局部变量,这就是为什么在return C()
内调用do()
才能正常工作。
教程:
http://docs.python.org/2/tutorial/classes.html
http://docs.python.org/2/tutorial/controlflow.html#defining-functions
答案 1 :(得分:1)
只有在类体内直接访问类变量才是非限定的。
当查找变量名称时,该过程有效this way(假设没有global
或nonlocal
声明):
在块的执行过程中,无论是函数定义还是类体,对象本身还不存在,所以显然你不能引用它。
让我们看看如果在绑定算法中将类计入封闭范围,可能会发生什么:
x=3
class A:
def __init__(self):
A.x = 5
def foo(self):
print(x)
a=A()
a.foo()
类定义中A.x
没有绑定,因此print(x)
必须引用全局x,对吧?但是当调用a.foo()
时, 要引用A.x
。这不直观。与类范围不同,函数作用域是不可变的(实际上是不可访问的)。
此外,除了classvar
和global
之外,您还需要nonlocal
声明。它只适用于当前类,因此您还需要nonlocal classvar
语句...
我认为类不被视为“封闭范围”的另一个原因是允许class creation customization使用元类。但我不确定,