Python: 如何创建继承他人ABC的ABC?
Python: How to create an ABC that inherits from others ABC?
我正在尝试创建一个简单的抽象基础 class Abstract
,它连同它自己的方法提供了另外两个抽象基础 classes 的方法:Publisher
和 Subscriber
。当我尝试初始化基于 Abstract
的具体 class Concrete
时,出现此错误:无法创建一致的方法解析顺序 (MRO)对于基础 ABC、发布者、订阅者。正确的做法是什么?
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()
由此变化:
class Abstract(ABC, Publisher, Subscriber):
为此:
class Abstract(Publisher, Subscriber):
这两个子类已经是抽象类了,不需要再继承ABC
摘要 classes 不必在其碱基列表中包含 abc.ABC
。他们必须有 abc.ABCMeta
(或后代)作为他们的元 class,并且他们必须至少有一个抽象方法(或其他重要的东西,如抽象 属性),否则它们将被视为具体的。 (Publisher
没有抽象方法,所以它实际上是具体的。)
从 ABC
继承只是将 ABCMeta
作为 class 的元 class 的一种方式,对于比元 [=38 更习惯继承的人来说=]es,但这不是唯一的方法。您还可以从另一个 class 继承 ABCMeta
作为其元 class,或明确指定 metaclass=ABCMeta
。
在你的例子中,继承自 Publisher
和 Subscriber
已经将 Abstract
的元 class 设置为 ABCMeta
,因此继承自 ABC
是多余的。从 Abstract
的基础 class 列表中删除 ABC
,一切正常。
或者,如果你真的出于某种原因想要ABC
在那里,你可以将它移到基础class列表的末尾,这将解决 MRO 冲突 - 首先说您希望 ABC
方法覆盖其他 classes 的方法,这与其他 classes 是子 [=38] 的事实相冲突=]es of ABC
.
我正在尝试创建一个简单的抽象基础 class Abstract
,它连同它自己的方法提供了另外两个抽象基础 classes 的方法:Publisher
和 Subscriber
。当我尝试初始化基于 Abstract
的具体 class Concrete
时,出现此错误:无法创建一致的方法解析顺序 (MRO)对于基础 ABC、发布者、订阅者。正确的做法是什么?
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()
由此变化:
class Abstract(ABC, Publisher, Subscriber):
为此:
class Abstract(Publisher, Subscriber):
这两个子类已经是抽象类了,不需要再继承ABC
摘要 classes 不必在其碱基列表中包含 abc.ABC
。他们必须有 abc.ABCMeta
(或后代)作为他们的元 class,并且他们必须至少有一个抽象方法(或其他重要的东西,如抽象 属性),否则它们将被视为具体的。 (Publisher
没有抽象方法,所以它实际上是具体的。)
从 ABC
继承只是将 ABCMeta
作为 class 的元 class 的一种方式,对于比元 [=38 更习惯继承的人来说=]es,但这不是唯一的方法。您还可以从另一个 class 继承 ABCMeta
作为其元 class,或明确指定 metaclass=ABCMeta
。
在你的例子中,继承自 Publisher
和 Subscriber
已经将 Abstract
的元 class 设置为 ABCMeta
,因此继承自 ABC
是多余的。从 Abstract
的基础 class 列表中删除 ABC
,一切正常。
或者,如果你真的出于某种原因想要ABC
在那里,你可以将它移到基础class列表的末尾,这将解决 MRO 冲突 - 首先说您希望 ABC
方法覆盖其他 classes 的方法,这与其他 classes 是子 [=38] 的事实相冲突=]es of ABC
.