web-dev-qa-db-ja.com

「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
49
Antonio Araujo

ドキュメントの状態 [ドキュメント]

ユーザー定義の基本クラスでは、メソッドをオーバーライドするために派生クラスが必要な場合、またはクラスを開発中に実際の実装を追加する必要があることを示すため、抽象メソッドはこの例外を発生させる必要があります。

主なユースケースは、このエラーは継承されたクラスに実装する必要がある抽象メソッドを示していますが、TODOマーカーの表示など、好きなように使用できることに注意してください。

45
Uriel

rielの言う のように、子クラスで実装される抽象クラスのメソッドを対象としていますが、TODOを示すためにも使用できます。

最初のユースケースには、代替手段 Abstract Base Classes があります。これらは抽象クラスの作成に役立ちます。

Python 3の例を次に示します。

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を取得することです。

19
Jérôme

代わりにそれがあったかどうかを検討してください:

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

    def cleanTileAtPosition(self, pos):
        pass

    def isTileCleaned(self, m, n):
        pass

そして、サブクラスを作成し、isTileCleaned()の方法を伝えるのを忘れるか、おそらく、isTileCLeaned()とタイプミスする可能性があります。次に、コードで呼び出すと、Noneが取得されます。

  • オーバーライドされた関数を取得しますか?絶対にありません。
  • Noneは有効な出力ですか?知るか。
  • それは意図した動作ですか?ほぼ間違いない。
  • エラーが発生しますか?場合によります。

raise NotImplmentedErrorforcesあなたがそれを実装するように、あなたはそれを実装するようにwill例外をスローする実行するまで実行します。これにより、多くのサイレントエラーが削除されます。 むき出しの例外はほとんど良い考えではありません :の理由と似ています。人々が間違いを犯し、これが敷物の下に流されないようにするためです。

注:他の回答で述べたように、抽象基本クラスを使用すると、エラーがフロントロードされ、それらを実装するまでプログラムが実行されないため(NotImplementedErrorでは、実際に呼び出された場合にのみ例外がスローされます).

15
TemporalWolf

@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
1
Simeon Aleksov