記述子は、他のオブジェクトのプロパティにアクセスするときに実行される操作を定義する Python オブジェクトです。記述子を使用すると、プロパティの計算、プロパティ値のキャッシュ、プロパティ アクセスの制御など、さまざまな動作を実装できます。記述子を使用してプロパティのアクセス動作をカスタマイズし、プロパティの使用ごとに重複したコードの作成を回避します。
インスタンス属性、クラス属性、静的属性を含む任意のクラスの属性で記述子を使用できます。 Python プログラミングの記述子は、Python 言語を深く理解し、高度なプログラミング スキルを持つプログラマーにとって非常に役立つ高度な機能です。
Python ディスクリプタは、ディスクリプタ プロトコルを実装することで定義されます。記述子プロトコルは Python オブジェクト プロトコルの一種で、__get__()
、__set__()
、および __delete__()
の 3 つのメソッドを定義します。
Python インタープリターがオブジェクトのプロパティにアクセスするとき、最初にそのプロパティが記述子であるかどうかを確認します。属性が記述子の場合は、__get__() メソッドを呼び出して属性値を取得します。属性が記述子でない場合は、属性値が直接返されます。
Python 記述子を使用して属性アクセス動作を制御したい場合は、記述子プロトコルに __get__()
、__set__()
、および # を実装する必要があります。 #__delete__()メソッド内に少なくとも 1 つのメソッド。これらのメソッドの具体的な説明は次のとおりです。
__get__(self, instance, owner): 属性値を取得するために使用されます。アクセスされる属性がインスタンスの場合、instance パラメータはインスタンス オブジェクト、owner パラメータはクラス オブジェクトです。アクセスされる属性がクラスの場合、インスタンス パラメータは None で、owner パラメータはクラス オブジェクトです。
__set__(self,instance,value): 属性値を設定するために使用されます。属性値がインスタンスによって設定される場合、instance パラメーターはインスタンス オブジェクトであり、value パラメーターは設定される値です。属性値がクラスによって設定される場合、instance パラメーターは None で、value パラメーターは設定される値です。
__delete__(self,instance): 属性値を削除するために使用されます。削除されるプロパティ値がインスタンスの場合、インスタンス パラメーターはインスタンス オブジェクトです。属性値がクラスから削除される場合、インスタンス パラメーターは None になります。
Python 記述子の使用方法
class SumDescriptor: def __init__(self, a, b): self.a = a self.b = b def __get__(self, instance, owner): return getattr(instance, self.a) + getattr(instance, self.b) class MyClass: def __init__(self, a, b): self.a = a self.b = b self.sum = SumDescriptor('a', 'b')上記のコードでは、SumDescriptor は、__get__() メソッドを使用して a 属性と b 属性の合計を計算する記述子です。 MyClass は、プロパティ a および b を含むクラスであり、SumDescriptor のインスタンスである sum プロパティも定義します。 MyClass を使用してインスタンスを作成する場合、手動で計算することなく、sum 属性にアクセスすることで a 属性と b 属性の合計を取得できます。
>>> obj = MyClass(1, 2) >>> obj.sum 3キャッシュ属性値
class CachedProperty: def __init__(self, func): self.func = func self.__name__ = func.__name__ def __get__(self, instance, owner): if instance is None: return self value = self.func(instance) setattr(instance, self.__name__, value) return value class MyClass: def __init__(self, data): self._data = data @CachedProperty def processed_data(self): # Perform some slow computation result = ... return result上記のコードでは、
CachedProperty は、
__get__() メソッドを使用してプロパティ値をキャッシュする記述子です。 。
MyClass は、
_data 属性を含むクラスであり、
processed_data 属性を定義します。この属性は、
@CachedProperty デコレータを使用してキャッシュを実装します。
processed_data 属性にアクセスするとき、属性値がすでにキャッシュに存在する場合は、キャッシュされた値が直接返されます。それ以外の場合、プロパティ値が計算され、キャッシュに保存されます。
class ReadOnlyDescriptor: def __init__(self, value): self.value = value def __get__(self, instance, owner): return self.value def __set__(self, instance, value): raise AttributeError("can't set attribute") class MyClass: def __init__(self, data): self._data = ReadOnlyDescriptor(data)上記のコードでは、
ReadOnlyDescriptor は、
__set__() メソッドを使用して Make を禁止する記述子です。プロパティの変更。
MyClass は、読み取り専用属性を定義する
_data 属性を含むクラスです。
_data 属性を変更しようとすると、
AttributeError 例外がスローされます。
property デコレータも用意されています。
property デコレータを使用すると、メソッドを読み取り専用プロパティ、書き込み可能プロパティ、または読み取り/書き込みプロパティに変換できます。以下は、カスタム属性アクセス制御のサンプル コードです:
class MyClass: def __init__(self, value): self._value = value @property def value(self): return self._value @value.setter def value(self, new_value): if new_value < 0: raise ValueError("value must be non-negative") self._value = new_value
在上面的代码中,value
方法被转换为一个属性。@property
装饰器将value
方法转换为只读属性,@value.setter
装饰器将value
方法转换为可写属性。当我们尝试对value
属性进行修改时,如果新值小于0
,则引发ValueError
异常。
以上がPython で記述子を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。