2017-06-01 82 views
11

難道要記住自己和你的團隊正確實施課程嗎? 我不完全得到使用抽象類是這樣的:何時使用'raise NotImplementedError'?

class RectangularRoom(object): 
    def __init__(self, width, height): 
     raise NotImplementedError 

    def cleanTileAtPosition(self, pos): 
     raise NotImplementedError 

    def isTileCleaned(self, m, n): 
     raise NotImplementedError 
+2

跨網站欺騙:https://softwareengineering.stackexchange.com/q/231397/110531 – jonrsharpe

+1

我會說:當它滿足[「最小驚訝的原則」](https://en.wikipedia.org /維基/ Principle_of_least_astonishment)。 – MSeifert

回答

15

由於文檔指出[docs]

在用戶定義的基類,抽象方法應該提高這個例外,當他們需要派生類覆蓋該方法,或者正在開發類以指示仍需要添加真實實現。

注意,雖然主要說明使用情況下,這是錯誤的,應該在繼承的類實現抽象方法的指示,你可以用它反正你想,像一個TODO標誌的指示。

+0

對於抽象方法,我更喜歡使用'abc'(請參閱[我的回答](https://stackoverflow.com/a/44316506/4653485))。 –

0

你可能想使用@property裝飾,

>>> class Foo(): 
...  @property 
...  def todo(self): 
...    raise NotImplementedError("To be implemented") 
... 
>>> f = Foo() 
>>> f.todo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in todo 
NotImplementedError: To be implemented 
+0

我不明白這是如何解決問題的,這是*何時使用*。 – TemporalWolf

0

考慮一下,如果相反,它是:

class RectangularRoom(object): 
    def __init__(self, width, height): 
     pass 

    def cleanTileAtPosition(self, pos): 
     pass 

    def isTileCleaned(self, m, n): 
     pass 

,你繼承,卻忘了告訴它如何isTileCleaned()或者,也許更容易,將其打錯爲isTileCLeaned()。然後在你的代碼中,當你調用它的時候你會得到一個None

  • 你會得到你想要的重載函數嗎?當然不。
  • None有效輸出?誰知道。
  • 這是預期的行爲?幾乎肯定不是。
  • 你會得到一個錯誤?這取決於。

力量你實現它,因爲它會直到你這樣做拋出異常。這消除了很多無聲錯誤。它類似於爲什麼一個bare except is almost never a good idea:因爲人們犯錯誤,這確保他們不會在地毯下掃蕩。

3

作爲Uriel says,它是指抽象類中應該在子類中實現的方法,但也可用於指示TODO。

Python 3帶有第一個用例的替代方案:Abstract Base Classes。那些幫助創建抽象類:

class C(abc.ABC): 
    @abstractmethod 
    def my_abstract_method(self, ...): 
    ... 

當實例C,你會因爲my_abstract_method是抽象得到一個錯誤。你需要在兒童課堂上實施它。

TypeError: Can't instantiate abstract class C with abstract methods my_abstract_method 

子類C和實施my_abstract_method

class D(C): 
    def my_abstract_method(self, ...): 
    ... 

現在您可以實例化D

C.my_abstract_method不一定是空的。可以使用super()D調用它。

NotImplementedError相比,優勢在於您在實例化時獲得明確的Exception,而不是在方法調用時。

+1

也可以在Python 2.6+中使用。只需'從abc導入ABCMeta,抽象方法'並用'__metaclass__ = ABCMeta'定義您的ABC。文檔:https://docs.python.org/2/library/abc.html – BoltzmannBrain

相關問題