ホームページ  >  記事  >  バックエンド開発  >  Python で記述子を使用する方法

Python で記述子を使用する方法

PHPz
PHPz転載
2023-05-29 08:19:281317ブラウズ

    概要

    記述子は、他のオブジェクトのプロパティにアクセスするときに実行される操作を定義する 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 記述子の使用方法

    アプリケーション シナリオ

    Python の記述子は、属性の計算、属性値のキャッシュ、属性アクセス制御の実装など、さまざまな状況で使用できます。以下に、Python 記述子を使用した例をいくつか示します。

    計算プロパティ

    計算プロパティは、他のプロパティから計算されるプロパティです。たとえば、記述子を使用すると、2 つの数値プロパティを追加する計算プロパティを作成できます。以下は、計算されたプロパティを実装するサンプル コードです。

    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

    キャッシュ属性値

    もう 1 つの一般的な用途は、属性値のキャッシュです。記述子を使用すると、属性値をキャッシュできるため、特に属性値の計算が遅い場合や大量のデータの場合に、プログラムのパフォーマンスが向上します。以下は、プロパティ値をキャッシュするためのサンプル コードです。

    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 例外がスローされます。

    カスタム プロパティ アクセス コントロール

    上で紹介した基本的な記述子に加えて、Python にはカスタム プロパティ アクセス コントロールの定義に使用できる

    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 サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。