後続の各サブクラスでオーバーライドする関数を持つ抽象基本クラスを検討してください。abc モジュールと ABCMeta を使用します。デコレーターによって指定されたタイプの関数を作成するために実装するサブクラス/開発者を使用して装飾する@abstractproperty
か、@abstractmethod
実際に強制しますか? 私の実験から、メソッドで抽象プロパティをオーバーライドし、サブクラスのプロパティで抽象メソッドをオーバーライドできます。
この考えは間違っていますか?
後続の各サブクラスでオーバーライドする関数を持つ抽象基本クラスを検討してください。abc モジュールと ABCMeta を使用します。デコレーターによって指定されたタイプの関数を作成するために実装するサブクラス/開発者を使用して装飾する@abstractproperty
か、@abstractmethod
実際に強制しますか? 私の実験から、メソッドで抽象プロパティをオーバーライドし、サブクラスのプロパティで抽象メソッドをオーバーライドできます。
この考えは間違っていますか?
その考えは正しいです。コードは aと a をABCMeta
区別しません。abstractproperty
abstractmethod
これらのデコレーターは両方とも、装飾されたアイテム に属性を追加します.__isabstractmethod__
。これは、定義した ABC に属性 (a )ABCMeta
を追加するために使用します。この型は、リストされている名前のいずれにも具体的な実装がないクラスのインスタンスを作成しないように保護します。そこでは、関数とプロパティのチェックは行われません。.__abstractmethods__
frozenset
object
.__abstractmethods__
説明する:
>>> from abc import *
>>> class C:
... __metaclass__ = ABCMeta
... @abstractmethod
... def abstract_method(self): pass
... @abstractproperty
... def abstract_property(self): return 'foo'
...
>>> C.__abstractmethods__
frozenset(['abstract_method', 'abstract_property'])
サブクラスでこれらの新しいオーバーライドを作成することにより、ABCMeta
クラスは属性を持つメソッドまたはプロパティをより少なく見つけ. __isabstractmethod__
、結果として得られる__abstractmethods__
セットをより小さくします。セットが空になると、そのようなサブクラスのインスタンスを作成できます。
これらのチェックはABCMeta.__new__
コンストラクターで行われ、記述子の型と一致するチェックは行われません。
cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
# Compute set of abstract method names
abstracts = set(name
for name, value in namespace.items()
if getattr(value, "__isabstractmethod__", False))
for base in bases:
for name in getattr(base, "__abstractmethods__", set()):
value = getattr(cls, name, None)
if getattr(value, "__isabstractmethod__", False):
abstracts.add(name)
cls.__abstractmethods__ = frozenset(abstracts)
ABCMeta
メソッドをオーバーライドするサブクラスを作成__new__
し、基本クラスで名前が付けられた抽象メソッドまたはプロパティが、代わりに非抽象メソッドまたはプロパティと実際に一致することを確認する必要がありますcls
。