pythonメタクラスプログラミング(1)Property

2638 ワード

時々、オブジェクトのプロパティをより強く制御したい:たとえば、温度、年齢などの一定の範囲内の値を指定したい場合、または値を割り当てる場合にタイプの値を指定したい場合、たとえば別のプロパティ値に基づいて動的に調整したい場合(体の健康状態を表す属性は体温によって変化します).pythonのproperty装飾器を使うことができます.
以上は比較的公式の説明で、もしあなたがJavaについて知っているならば、Javaの中の属性はすべて私有であることを知っているべきで、対外的にgettersetterの方法を提供します.pythonのproperty装飾器もこれと同様であるが、パッケージされた ()ではなく、 のように直接使用される.
一、@property装飾器の使い方
例:
class Person:
    def __init__(self, age, create_date):
        self._age = age

    # Getter   
    @property
    def age(self):
        return self._age

    # Setter   
    @age.setter
    def age(self, value):
        if not isinstance(value, int):
            raise TypeError('      int')
        self._age = age

    # Deleter   
    @age.deleter
    def age(self):
        raise AttributeError("        ")


if __name__ == '__main__':
    person = Person(29)
    #                    `age`
    print(person.age)

上記の方法では、@propertyを使用し、通常の属性のように取得したり、値を付与したりすることができます.
上記のコードには3つの関連メソッドがあり、この3つのメソッドの名前は同じでなければなりません.最初の方法はgetter関数であり、ageを属性にする.他の2つの方法はage属性にsetter関数とdeleter関数を追加した.
パッケージageのみであるもよく、強調すべきはage属性が作成された後、後の2つの装飾器@ageのみである.setterと@age.deleterは定義できます.
二、いつ@property装飾器を使うか
1.属性が変化する
クラスgetter を定義すると
class Person:
    def __init__(self, age, create_date):
        self.age = age
        self.create_date = create_date
    
if __name__ == '__main__':
    person = Person(29, date(1990,9,9))
    #           
    print(person.age) 

しばらくして、あなたは突然思い出して、直接PersonPersonの属性を取得するべきではありませんて、年齢は時間の変化に従って変化するので、私达は1つのageの方法を提供するべきで、しかしコードの中で多くの地方はすでにget_age()を使って、この时私达はperson.ageを使って@property パッケージのageを使うことができて、別の場所でperson.ageを使用すると、新しいパッケージの方法が転用されます.
2.文法を簡潔にするためにpythonは簡潔な文法を提唱し、 は属性のように直接アクセスすることができ、動詞は方法にカプセル化されるべきだと考えている.例えば、clientというネットワークオブジェクトをカプセル化しています.urlを持っています.次の2つの書き方のように、2つ目のほうが気持ちがいいと思っている人もいます.特に関数のチェーン呼び出しでは.
parse(client.get_url())

parse(client.url)

リファレンスドキュメント
  • https://docs.python.org/zh-cn/3/reference/datamodel.html?highlight=descriptor#implementing-descriptors
  • https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p06_create_managed_attributes.html
  • https://cizixs.com/2015/12/31/python-descriptor-introduction/
  • https://www.jianshu.com/p/3807b9b36d96