2013-07-19 19 views
0

我有一個類可調用的類A。我還有一個叫做BA的子類,我不想調用它。當我嘗試調用它時,它應該提高正常的「不可調用」TypeError可調用類的不可調用子類

class A(): 
    def __call__(self): 
     print "I did it" 

class B(A): 
    def __call__(self): 
     raise TypeError("'B' object is not callable") 

正如您所看到的,我現在的解決方案是提高正常TypeError的副本。這感覺不對,因爲我只是複製標準python異常的文本。如果有一種方法將子類標記爲不可調用,然後讓python處理該屬性,那會更好(在我看來)。

考慮到B類是可調用類A的子類,使B類不可調用的最佳方法是什麼?

+0

嗯。您是否考慮過標準['NotImplementedError'](http://docs.python.org/2/library/exceptions.html#exceptions.NotImplementedError)? – woozyking

+5

您可能想重新考慮您的設計。如果B沒有實現A聲明的方法,你真的可以說B是一種A嗎? – Kevin

回答

0

您可以使用Python元類覆蓋類型創建。在創建對象之後,我將父項__call__方法替換爲另一個拋出異常:

>>> class A(object): 
    def __call__(self): 
     print 'Called !' 


>>> class MetaNotCallable(type): 
    @staticmethod 
    def call_ex(*args, **kwargs): 
      raise NotImplementedError() 

    def __new__(mcs, name, bases, dict): 
     obj = super(MetaNotCallable, mcs).__new__(mcs, name, bases, dict) 
     obj.__call__ = MetaNotCallable.call_ex # Change method ! 
     return obj 


>>> class B(A): 
    __metaclass__ = MetaNotCallable 


>>> a = A() 
>>> a() 
Called ! 
>>> b = B() 
>>> b() 

Traceback (most recent call last): 
    File "<pyshell#131>", line 1, in <module> 
    b() 
    File "<pyshell#125>", line 4, in call_ex 
    raise NotImplementedError() 
NotImplementedError 
+0

爲什麼元類在這裏是必要/有用的?看起來更容易,只是直接在'B'中定義'__call__'方法來引發異常。 – augurar

+0

作者剛剛這樣做,所以我想提出其他的東西......我同意它可能看起來過度殺戮,但它揭示了先進的Python功能 - 如果涉及幾個類,您只需設置__metaclasse__屬性和你完成了 - 不需要重複(這是邪惡的!)。 – Emmanuel