web-dev-qa-db-ja.com

Pythonの抽象メソッド

Python(3.2)のabstract protectedメソッドのようなものが必要です:

class Abstract:
    def use_concrete_implementation(self):
        print(self._concrete_method())

    def _concrete_method(self):
        raise NotImplementedError()


class Concrete(Abstract):
    def _concrete_method(self):
        return 2 * 3

NotImplementedErrorを発生させるためだけに「abstract」メソッドを定義することは実際に役立ちますか?

抽象メソッドにアンダースコアを使用するのは良いスタイルですか?他の言語ではprotectedになりますか?

抽象基本クラス(abc)は何かを改善しますか?

22
deamon

Pythonでは、通常、このような抽象メソッドをまとめて使用することは避けます。ドキュメントによってインターフェースを定義し、渡されたオブジェクトがそのインターフェースを満たすと単純に想定します(「ダックタイピング」)。

抽象メソッドを使用して抽象基本クラスを本当に定義したい場合は、 abc モジュールを使用してこれを行うことができます。

_from abc import ABCMeta, abstractmethod

class Abstract(metaclass=ABCMeta):
    def use_concrete_implementation(self):
        print(self._concrete_method())

    @abstractmethod
    def _concrete_method(self):
        pass

class Concrete(Abstract):
    def _concrete_method(self):
        return 2 * 3
_

繰り返しますが、これは通常のPython方法ではありません。abcモジュールの主な目的の1つは、isinstance()をオーバーロードするメカニズムを導入することでした。 、ただし、isinstance()チェックは通常、ダックタイピングを優先して回避されます。必要に応じて使用しますが、インターフェイスを定義するための一般的なパターンとしては使用しません。

39
Sven Marnach

疑わしい場合は、 Guidoと同じようにしてください。

アンダースコアはありません。 「abstractメソッド」を、NotImplementedErrorを発生させるワンライナーとして定義するだけです。

class Abstract():
    def ConcreteMethod(self):
        raise NotImplementedError("error message")
6
Triptych

基本的に、ここでは基本クラスの空のメソッドは必要ありません。このようにしてください:

class Abstract:
    def use_concrete_implementation(self):
        print(self._concrete_method())

class Concrete(Abstract):
    def _concrete_method(self):
        return 2 * 3

実際、通常、Pythonの基本クラスは必要ありません。すべての呼び出しは動的に解決されるため、メソッドが存在する場合は呼び出され、存在しない場合はAttributeErrorが発生します。

注意:ドキュメントで_concrete_methodはサブクラスで実装する必要があります。

0
Björn Pollex