gpt4 book ai didi

python-3.x - 具有指定元类的 Python abc 继承

转载 作者:行者123 更新时间:2023-12-03 23:10:59 32 4
gpt4 key购买 nike

如果类指定了元类,那么从 ABC 继承的正确方法是什么?

直截了当的尝试

class KindMeta(type):
...

class Kind(ABC, metaclass=KindMeta):
...

导致 TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
在 KindMeta 中继承 ABCMeta 似乎有点错误,因为 mcs也用于创建非抽象类。

创建从 KindMeta 继承的自定义 ABC 听起来也不好。

有没有更好的处理方法?或者哪个解决方案更 Pythonic 并且应该被首选?

最佳答案

您必须创建第二个元类,继承自您的原始元类和 abc.ABCMeta并将该元类用作所需类的元类。

如果您的元类构造正确,请使用 super()调用它实现的所有(特殊)方法,它就像这样简单:

import abc 
...

class KindMeta(type):
...

class CombinedMeta(KindMeta, abc.ABCMeta):
pass

class Kind(ABC, metaclass=CombinedMeta):
...

如果您的元类没有使用 super() , 但调用硬编码 type方法,你必须改变它才能这样做。对于某些方法,例如 __prepare____call__ , 不给通讯员打电话是有道理的
super()方法取决于你在做什么,我认为没有必要运行 ABCMeta 中的对应方法.
而且,当然,只有当您不想或不能更改已有的元类,或者如果您希望您的元类用于其他不使用 ABC 的类时,才需要这样做 -

否则,你可以让你自己的元类继承 ABCMeta本身 - 无需创建第三个元类来结合两者:

import abc 
...

class KindMeta(abc.ABCMeta):
...

另一方面,如果您使用 Python 的元类 + 类构造机制来创建“不完全是类”的对象(例如 zope.interface 包确实用于创建接口(interface)),您必须决定 (1)如果在 abc.ABC 中使用它是有意义的根本,其次,如果必须运行 ABCMeta 中的对应方法(通常是的,如果您需要该功能)。在这种情况下,您必须适本地自定义您的元类 - 这可能包括强制将具有多重继承的类组合(即使您可以仅从 ABCMeta 继承)以防止它调用 type.__new__ (如果这是您的意图):

class KindMeta(type):
def __new__(mcls, name, bases, ns, **kw):
cls = ExistingClassRegistry[name]
return cls

class CombinedMeta(abc.ABCMeta, KindMeta):
# note the reversed order - ABCMeta will run first
# and call super().__new__ which runs KindMeta.__new__ and
# does not forward to type.__new__
pass


关于python-3.x - 具有指定元类的 Python abc 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57349105/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com