如何子类化 ABCMeta

Pro*_*o Q 7 python metaclass subclass python-3.x

通常,为了子类化一个类,我会做类似的事情

class Subby(Parenty):
    def __init__(self):
        Parenty.__init__(self)
Run Code Online (Sandbox Code Playgroud)

但现在我正在尝试子类化元类,特别是 ABCMeta,所以我正在做

import ABCMeta

class Subby(ABCMeta):
    def __init__(self):
       ABCMeta.__init__(self) #this never seems to run

    def __new__(mcls, name, bases, namespace):
        cls = ABCMeta.__new__(mcls, name, bases, namespace)
        return cls
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试将其子类化为Subby元类时,例如

class newClass(metaclass=Subby):
    pass
Run Code Online (Sandbox Code Playgroud)

我得到了错误TypeError: __init__() takes 1 positional argument but 4 were given

这是为什么?如何正确子类化 ABCMeta?

Jim*_*ard 4

从数据模型来看:

\n\n
\n

如果__new__()返回 的实例,则将像 一样调用cls新的 instance\xe2\x80\x99s方法,其中 self 是新实例,其余参数与传递给 的参数相同。__init__()__init__(self[, ...])__new__()

\n
\n\n

因此,正如 @user2357112 所说,签名必须匹配

\n\n

尽管如此,如果您只是想创建 ABC,实际上没有理由定义__init__ABC 。__new__只需创建它并用于.register注册符合要求的类即可。(可选)创建许多抽象方法和__subclasshook__检查一致性的方法。abc模块文档中已经存在一个很好的示例。

\n

  • 出于巧合,我刚刚写了一个答案,出于某种目的,我实际上_did_子类 ABCMeta 。(我以前没有见过这个问题)。我可能是这个问题的一个很好的例子 - http://stackoverflow.com/a/43884960/108205 (2认同)