Categories: Python

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

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

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

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

ディスクリプタとは?

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

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

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

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

__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を生成しています。

# ディスクリプタ
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__

ポイントは、MyClassクラスのコンストラクタでインスタンス変数を初期化する際にもディスクリプタが呼び出されることです。

まとめ

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

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

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

ゆうまる

独学でプログラミングを勉強しているおじさん。いろんな言語を勉強したが浅く広くなためあまり仕事につながらない。また忘れっぽいため自分のブログを備忘録としても使っている。産まれてこのかたずっとネコを飼ってる生粋のネコ派。最近お腹が出てきて筋トレに奮闘中!

Recent Posts

【Dart】コンストラクタのデフォルト引数について

Dartのコンストラクタのデフォルト引数…

2週間 ago

【Unity】有料アセットを無料で手に入れる方法

この記事では、Unityの有料アセットを…

4か月 ago

【Python】任意の秒数だけ処理を一時停止する方法【sleep()関数】

この記事では、Pythonで任意の秒数だ…

1年 ago

【Python】Wordの文書の新規作成と読み書き

この記事では、Pythonを使ってWor…

1年 ago

【Python】メタクラスって結局なんなの?

この記事では、Pythonのメタクラスに…

1年 ago