У меня есть базовый класс, от которого другие классы должны наследовать:Как объединить wxPython, abc и metaclass mixin?
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
. Я подумал: «О, да, я буду просто использовать подмешать»:
class PopulateToolbarMixin(metaclass=ABCMeta):
@abstractmethod
def _PopulateToolbar(self):
pass
PopulateToolbarMixin.register(wx.ToolBar)
PopulateToolbarMixin.register(AppToolbar)
Без изменений: все тот же TypeError
сообщений. Я подозреваю, что мне не хватает чего-то очевидного с использованием ABCMeta
; это не похоже на ошибку, специфичную для wxPython. Что я делаю не так? Есть ли лучший способ подойти к одной и той же проблеме?
Редактировать: Мне было указано в разговоре с коллегой, что нельзя смешивать метаклассы. С wx.ToolBar
, по-видимому, происходит от sip.wrappertype
, похоже, что это невозможно. Что еще, все еще Pythonic способ обработки подхода «абстрактного метода» здесь?
Mmm, good catch; это на самом деле то, что я изначально имел (забыл при повторном создании кода здесь). Увы, есть какой-то странный конфликт с wxPython, похоже, поскольку это не работает. –
Тогда казалось бы, что wx.ToolBar не является прямым экземпляром типа, и в этом случае вам не повезло; насколько я знаю, нет хорошего способа совместить метаклассы в Python. –