2013-06-24 31 views
2

我有一個基類其他類要繼承:如何將wxPython,abc和元類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。我想,「哦,對了,我就用一個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在這裏處理「抽象方法」方法的方式?

回答

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獲取類似抽象的行爲。

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.') 
+0

嗯,很好;這實際上是我原來的(在這裏重新創建代碼時忘了它)。唉,特別是與wxPython有某種奇怪的衝突,看起來,因爲這是行不通的。 –

+1

然後看起來wx.ToolBar不是一個類型的直接實例,在這種情況下,你運氣不好;據我所知,沒有一種將Python中的元類組合起來的好方法。 –

相關問題