2017-06-01 78 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

相关问题