class ExampleClass():
def Example(self):
self.nestedinstance = self.NestedClass()
self.nestedinstance.makenew()
class NestedClass():
def makenew(self):
newclass = NestedClass()
ExampleClass().Example()
当我运行上面的代码时,我得到了异常:name 'NestedClass' is not defined
是否有不同的方法来做到这与嵌套类或我做错了什么?
理想情况下,如果创建一个新实例,您希望使用classmethods,下面是一个示例:
class NestedClass():
@classmethod
def makenew(cls):
newclass = cls()
或者,如果你想使用当前实例创建一个实例(例如,如果你需要传递一些参数),那么你可以通过使用type(self)
或self.__class__
来获得类。
class NestedClass():
def makenew(self):
newclass = type(self)()
如果不知道你的用例,这可能不是你想要的。
你的错误来自python处理类的方式。
当遇到class
语句时,将运行类体,并将其定义的名称放在单独的名称空间中,该名称空间最终将成为类__dict__
。直到主体运行之后,类对象才被创建并绑定到它的名称。这意味着当您将class NestedClass:
放入class ExampleClass:
的主体中时,ExampleClass
还不存在,NestedClass
也不存在。间接地,因为这一点,所有新的类名称空间都存在于顶级可用的名称空间中(例如global或function),并且实际上并不相互嵌套。
作为这种操作顺序的结果,类主体根本不知道周围类的名称空间。因此,NestedClass
的名称空间指向全局名称空间,而不是ExampleClass
的__dict__
,就像您可能期望的那样,来自Java。在函数中定义的类可以在全局命名空间之前看到函数的局部命名空间,但仍然不能在封闭类中看到。
因此,newclass = NestedClass()
行抛出一个错误。在函数的命名空间或全局命名空间中不存在名称NestedClass
。有三种简单的解决方法:
-
使用静态作用域
__class__
:newclass = __class__()
-
通过类的全局名称引用类:
newclass = ExampleClass.NestedClass()
-
不要在Python中使用嵌套类。这通常是首选的方法。把
NestedClass
移到最上面。然后你的makenew
方法不需要修改就可以工作,ExampleClass.Example
可以直接引用NestedClass
,而不是作为self.NestedClass
。