Python:如何创建一个从其他ABC继承的ABC



我正在尝试创建一个简单的抽象基类Abstract,它与自己的方法一起提供了另外两个抽象基类的方法:PublisherSubscriber。当我尝试初始化基于Abstract构建的具体类Concrete时,我得到了以下错误:无法为基ABC、发布服务器、订阅服务器创建一致的方法解析顺序(MRO(。做这件事的正确方法是什么?

from abc import ABC, abstractmethod
class Publisher(ABC):

subscribers = set() 

def register(self, obj):
self.subscribers.add(obj)

def unregister(self, obj):
self.subscribers.remove(obj)

def dispatch(self, event):
print("dispatching", event)

class Subscriber(ABC):

@abstractmethod
def handle_event(self, event):
raise NotImplementedError

class Abstract(ABC, Publisher, Subscriber):

@abstractmethod
def do_something(self, event):
raise NotImplementedError

class Concrete(Abstract):
def handle_event(self, event):
print("handle_event")

def do_something(self, event):
print("do_something")


c = Concrete()

抽象类的基列表中不必有abc.ABC。它们必须有abc.ABCMeta(或子类(作为元类,并且必须至少有一个抽象方法(或其他重要的方法,如抽象属性(,否则它们将被视为具体的。(Publisher没有抽象的方法,所以它实际上是具体的。(

ABC继承只是将ABCMeta作为类的元类的一种方式,对于比元类更熟悉继承的人来说,但这不是唯一的方式。您也可以从另一个以ABCMeta为元类的类继承,或者显式指定metaclass=ABCMeta


在您的情况下,从PublisherSubscriber继承已经将Abstract的元类设置为ABCMeta,因此从ABC继承是多余的。从Abstract的基类列表中删除ABC,一切都会正常工作。

或者,如果您出于某种原因真的希望ABC在其中,您可以将其移动到基类列表的末尾,这将解决MRO冲突-首先说您希望ABC方法覆盖其他类的方法,这与其他类是ABC的子类的事实相冲突。

从此更改:

class Abstract(ABC, Publisher, Subscriber):

对此:

class Abstract(Publisher, Subscriber):

这两个子类已经是抽象的,因此不需要再次从ABC继承。

class摘要(发布者、订阅者、ABC(:

如果你想确保类不是可实例化的,这将是解决方案

相关内容

  • 没有找到相关文章

最新更新