Python

【Python】ディスクリプタの使い方について解説

この記事では、Pythonのディスクリプタ(Descriptor)について解説します。

ディスクリプタを使うことで属性の書き込み、読み込み、削除する際の動作をカスタマイズすることができます。

それでは、ディスクリプタの使い方を見ていきましょう❗️

ディスクリプタとは?

ディスクリプタとは、ディスクリプタプロトコルのメソッドが1つでも定義されているオブジェクトのことを言います。

ディスクリプタプロトコル
  • descr.__get__(self, obj, type=None) --> value
  • descr.__set__(self, obj, value) --> None
  • descr.__delete__(self, obj) --> None

上記の3つのメソッドいずれかを定義したオブジェクトを属性として参照させることでそれぞれのメソッドに対応した動作をオーバーライドすることができます。

それぞれのメソッドが定義する動作は以下の通りです。

__get__ 属性が参照された際の動作を定義します
__set__ 属性が更新された際の動作を定義します
__delete__ 属性が削除された際の動作を定義します

それでは、実際に定義して挙動を確かめてみましょう!

ディスクリプタの使い方

ディスクリプタは以下のように使用します。

  • STEP1
    定義

    クラスとしてディスクリプタを定義します。

    class ディスクリプタ名:
    
        def __init__(self):
            # 省略可能
            
        def __get__(self, obj, objtype=None):
            # 参照する際の動作の定義
            return 戻り値
    
        def __set__(self, obj, value)
            # 更新する際の動作の定義
    
        def __delete__(self, obj)
            # 削除する際の動作の定義
  • STEP2
    参照
    定義したディスクリプタをオブジェクトの属性として参照させます。

    class クラス名:
    
        変数名 = ディスクリプタ名()
  • STEP3
    呼び出し
    あとは普通にインスタンス化し、その変数にアクセスすることでディスクリプタプロトコルで定義した動作を呼び出すことができます。

    インスタンス名 = クラス名()
    
    インスタンス名.変数名
    >> __get__が呼び出される
    
    インスタンス名.変数名 = なんかしらの値
    >> __set__が呼び出される
    
    del インスタンス名.変数名
    >> __delete__が呼び出される

サンプル

以下のサンプルでは、ディスクリプタで動的にプライベートな_valueを生成しています。ポイントはMyClassクラスのコンストラクタでインスタンス変数を初期化する際にもディスクリプタが呼び出されることです。

# ディスクリプタ
class Descriptor:
        
    def __get__(self, obj, objtype=None):
        print('__get__')
        return obj._value

    def __set__(self, obj, value):
        print('__set__')
        obj._value = value

    def __delete__(self, obj):
        print('__delete__')
        del obj._value


class MyClass:

    value = Descriptor()

    def __init__(self, value):
        self.value = value


mc = MyClass(1)
>> __set__

print(mc.value)
>> __get__
>> 1

mc.value = 100
>> __set__

# ディスクリプタで動的に生成された「_value」にもアクセスできる
print(mc._value)
>> 100

del mc.value
>> __delete__

まとめ

この記事では、Pythonのディスクリプタについて解説しました。

使いこなせばかなり色々できそうなポテンシャルを感じますね〜😄 ディスクリプタはまだまだ奥深いのでさらに学びたい方は公式ドキュメントを参照してください。

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ