我有一个其他类应继承的基类:
class AppToolbar(wx.ToolBar):
''' Base class for the Canary toolbars '''
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# ... a few common implementation details that work as expected...
self._PopulateToolbar()
self.Realize()
基类没有(也不能)实现_PopulateToolbar()
;它应该是一个抽象的方法。因此,我认为使用abc
是一个很好的计划,所以我尝试了这个:
class AppToolbar(wx.ToolBar, metaclass=abc.ABCMeta):
# ... as above, but with the following added
@abc.abstractmethod
def _PopulateToolbar():
pass
也许不足为奇,尝试运行此导致TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
。我想,“哦,对,我只会使用mixin”:
class PopulateToolbarMixin(metaclass=ABCMeta):
@abstractmethod
def _PopulateToolbar(self):
pass
PopulateToolbarMixin.register(wx.ToolBar)
PopulateToolbarMixin.register(AppToolbar)
无变化:仍然是相同的TypeError
消息。我怀疑我在这里使用ABCMeta
时遗漏了一些明显的东西;这看起来不像wxPython特有的错误。我究竟做错了什么?有没有更好的方法来处理同样的问题?
编辑:我在与同事的对话中指出,不能混合使用元类。由于wx.ToolBar
显然来自sip.wrappertype
,因此看起来没有办法做到这一点。在这里处理“抽象方法”方法的另一种仍然是Pythonic的方法是什么?
答案 0 :(得分:1)
在你从wx.ToolBar和abc.ABCMeta继承的第一个例子中,你不希望AppToolbar成为abc.ABCMeta的子类,你希望AppToolbar成为一个实例。试试这个:
class AppToolbar(wx.ToolBar, metaclass=abc.ABCMeta):
# ... as above, but with the following added
@abc.abstractmethod
def _PopulateToolbar():
pass
虽然看得更近一些,但似乎你不能用abc.ABCMeta作为其元类来定义wx.Toolbar的子类,因为wx.Toolbar是除了bultins.type之外的元类的实例。但是,您可以从AppToolbar._PopulateToolbar中获取类似抽象的行为:
class AppToolbar(wx.ToolBar):
def _PopulateToolbar():
''' This is an abstract method; subclasses must override it. '''
raise NotImplementedError('Abstract method "_PopulateToolbar" must be overridden before it can be called.')