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 - 如果您继承自 typeABCMeta 本身,您会这样做 - 您的新 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())