Python 嵌套的元类(abc 模块)继承 类
Python metaclass (abc module) inheritance with nested classes
我写了一个 Python 3 元类,其中包含一个嵌套元类(带有 abc),例如:
class A_M(object, metaclass=abc.ABCMeta):
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
现在,像这样实施
class A(A_M):
class A_nested(A_nested_M):
def ...
不起作用。那么,我是不是错过了元类的用法,或者这种带有嵌套元类的实现根本不起作用?
你应该像这样实现你的class:
class A(A_M):
class A_nested(A_M.A_nested_M):
def ...
因为 A_nested_M
是一个内部 class,您应该像访问任何 class 属性一样访问它,即 A_M.A_nested_M
。参见 this link。
第一件事:
嵌套 class 声明对 Python 中的任何内容几乎没有用处。除非您使用嵌套的 class 层次结构本身作为硬编码名称空间来保留属性,否则您可能已经在做错事了。
您没有说明您的(实际)问题是什么以及您试图在那里实现什么,也没有说明您为什么使用 ABCmeta 元class。因此很难提出任何实际有用的答案 - 但我们可以尝试澄清一些事情:
首先:您不是在编写元class,正如您在文本"I've written a Python 3 metaclass containing a nested metaclass..."中建议的那样 - 您正在创建 具有 ABCmeta 作为它的元class。但是您并没有创建新的元 classes - 如果您继承自 type
或 ABCMeta
本身,您会这样做 - 您的新 class 将用于 metaclass=
后续(普通)classes 的参数。事实并非如此。
现在,其次,在最外层 A_M
class 的正文中定义的所有内容都将只是 "visible" 作为 A_M
本身的属性。那是错误的根源-当您尝试从 A_nested_M
继承时,您实际上应该写:
class A_M(object, metaclass=abc.ABCMeta):
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
class A(A_M):
class A_nested(A_M.A_nested_M):
def ...
请参阅 - A_M.A_nested_M
将使 Python 找到 A_nested
的超级 class:A_nested_M
的本地或全局名称空间中没有引用因为它仅作为 A_M
的属性存在于 class A_M...
语句的主体之外。
也就是说,这仍然没有用。如果你想让 A
class 的实例引用 A_nested
的 实例 ,你必须在 A.__init__()
调用中创建这些实例- 在这一点上,如果 A_nested
在 class 主体内或在模块级别声明没有区别:
class A_M(object, metaclass=abc.ABCMeta):
pass
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
class A_nested(A_nested_M):
...
class A(A_M):
def __init__(self):
self.nested = A_nested()
现在,这可能会有一些用处。您还可以声明 classes 实际上是嵌套的,但它们唯一有用的方法是创建它们的实例。与嵌套函数不同,嵌套 classes 无法访问在 "nesting" class 命名空间上声明的属性或变量(但通过限定名称引用它们。即在您的示例中,如果 A
class 将包含 b
class 方法,则 A_nested
中调用此方法的方法必须调用 A.b()
,不是 b()
)
我写了一个 Python 3 元类,其中包含一个嵌套元类(带有 abc),例如:
class A_M(object, metaclass=abc.ABCMeta):
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
现在,像这样实施
class A(A_M):
class A_nested(A_nested_M):
def ...
不起作用。那么,我是不是错过了元类的用法,或者这种带有嵌套元类的实现根本不起作用?
你应该像这样实现你的class:
class A(A_M):
class A_nested(A_M.A_nested_M):
def ...
因为 A_nested_M
是一个内部 class,您应该像访问任何 class 属性一样访问它,即 A_M.A_nested_M
。参见 this link。
第一件事: 嵌套 class 声明对 Python 中的任何内容几乎没有用处。除非您使用嵌套的 class 层次结构本身作为硬编码名称空间来保留属性,否则您可能已经在做错事了。
您没有说明您的(实际)问题是什么以及您试图在那里实现什么,也没有说明您为什么使用 ABCmeta 元class。因此很难提出任何实际有用的答案 - 但我们可以尝试澄清一些事情:
首先:您不是在编写元class,正如您在文本"I've written a Python 3 metaclass containing a nested metaclass..."中建议的那样 - 您正在创建 具有 ABCmeta 作为它的元class。但是您并没有创建新的元 classes - 如果您继承自 type
或 ABCMeta
本身,您会这样做 - 您的新 class 将用于 metaclass=
后续(普通)classes 的参数。事实并非如此。
现在,其次,在最外层 A_M
class 的正文中定义的所有内容都将只是 "visible" 作为 A_M
本身的属性。那是错误的根源-当您尝试从 A_nested_M
继承时,您实际上应该写:
class A_M(object, metaclass=abc.ABCMeta):
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
class A(A_M):
class A_nested(A_M.A_nested_M):
def ...
请参阅 - A_M.A_nested_M
将使 Python 找到 A_nested
的超级 class:A_nested_M
的本地或全局名称空间中没有引用因为它仅作为 A_M
的属性存在于 class A_M...
语句的主体之外。
也就是说,这仍然没有用。如果你想让 A
class 的实例引用 A_nested
的 实例 ,你必须在 A.__init__()
调用中创建这些实例- 在这一点上,如果 A_nested
在 class 主体内或在模块级别声明没有区别:
class A_M(object, metaclass=abc.ABCMeta):
pass
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
class A_nested(A_nested_M):
...
class A(A_M):
def __init__(self):
self.nested = A_nested()
现在,这可能会有一些用处。您还可以声明 classes 实际上是嵌套的,但它们唯一有用的方法是创建它们的实例。与嵌套函数不同,嵌套 classes 无法访问在 "nesting" class 命名空间上声明的属性或变量(但通过限定名称引用它们。即在您的示例中,如果 A
class 将包含 b
class 方法,则 A_nested
中调用此方法的方法必须调用 A.b()
,不是 b()
)