如何在 Python 中的 class 中创建嵌套 class 的实例?
How do I create an instance of a nested class from within that class in Python?
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
是否有其他方法可以使用嵌套 class 或我做错了什么?
理想情况下,如果创建新实例,您希望使用 class 方法,这是您如何操作的示例:
class NestedClass():
@classmethod
def makenew(cls):
newclass = cls()
或者,如果您想使用当前实例创建一个实例(例如,如果您需要传递一些参数),那么您可以通过使用 type(self)
或 self.__class__
.
class NestedClass():
def makenew(self):
newclass = type(self)()
虽然不知道您的用例,但这可能不是您想要的。
您的错误来自 python 处理 classes 的方式。
当遇到class
语句时,class的主体是运行,它定义的名字放在单独的命名空间中,最终会成为class __dict__
。 class 对象不会被创建并绑定到它的名字,直到(很好)在主体有 运行 之后。这意味着当你把 class NestedClass:
放在 class ExampleClass:
的主体中时,ExampleClass
还不存在,NestedClass
也不存在。间接地,因此,所有新的 class 命名空间都位于可用的顶级命名空间(例如全局或函数)中,并且实际上并未相互嵌套。
作为这种操作顺序的结果,class 主体根本不知道周围 classes 的名称空间。因此 NestedClass
的命名空间会查看全局命名空间,而不是 ExampleClass
的 __dict__
,正如您可能期望来自 Java 的命名空间。在函数中定义的 class 将能够在全局变量之前看到函数局部命名空间,但仍然不能看到封闭的 class.
因此,行 newclass = NestedClass()
引发了一个错误。函数名称空间或全局名称空间中不存在名称 NestedClass
。提供三种简单的解决方法:
使用静态范围__class__
:
newclass = __class__()
通过全局名称引用 class:
newclass = ExampleClass.NestedClass()
不要在 Python 中使用嵌套的 classes。这通常是首选方法。只需将 NestedClass
移动到顶层即可。然后你的 makenew
方法无需修改就可以工作,并且 ExampleClass.Example
可以直接引用 NestedClass
而不是 self.NestedClass
.
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
是否有其他方法可以使用嵌套 class 或我做错了什么?
理想情况下,如果创建新实例,您希望使用 class 方法,这是您如何操作的示例:
class NestedClass():
@classmethod
def makenew(cls):
newclass = cls()
或者,如果您想使用当前实例创建一个实例(例如,如果您需要传递一些参数),那么您可以通过使用 type(self)
或 self.__class__
.
class NestedClass():
def makenew(self):
newclass = type(self)()
虽然不知道您的用例,但这可能不是您想要的。
您的错误来自 python 处理 classes 的方式。
当遇到class
语句时,class的主体是运行,它定义的名字放在单独的命名空间中,最终会成为class __dict__
。 class 对象不会被创建并绑定到它的名字,直到(很好)在主体有 运行 之后。这意味着当你把 class NestedClass:
放在 class ExampleClass:
的主体中时,ExampleClass
还不存在,NestedClass
也不存在。间接地,因此,所有新的 class 命名空间都位于可用的顶级命名空间(例如全局或函数)中,并且实际上并未相互嵌套。
作为这种操作顺序的结果,class 主体根本不知道周围 classes 的名称空间。因此 NestedClass
的命名空间会查看全局命名空间,而不是 ExampleClass
的 __dict__
,正如您可能期望来自 Java 的命名空间。在函数中定义的 class 将能够在全局变量之前看到函数局部命名空间,但仍然不能看到封闭的 class.
因此,行 newclass = NestedClass()
引发了一个错误。函数名称空间或全局名称空间中不存在名称 NestedClass
。提供三种简单的解决方法:
使用静态范围
__class__
:newclass = __class__()
通过全局名称引用 class:
newclass = ExampleClass.NestedClass()
不要在 Python 中使用嵌套的 classes。这通常是首选方法。只需将
NestedClass
移动到顶层即可。然后你的makenew
方法无需修改就可以工作,并且ExampleClass.Example
可以直接引用NestedClass
而不是self.NestedClass
.