2

我有一个基类,其他类应该继承它:

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();它应该是一个抽象方法。因此,我认为 usingabc是一个很好的计划,所以我尝试了这个:

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 的方法是什么?

4

1 回答 1

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.')
于 2013-06-24T23:44:57.753 回答