この記事では、Python での @property デコレーターの技術的な使用法 (コード例) を紹介します。これは一定の参考価値があります。必要な友人は参照できます。お役に立てば幸いです。
@プロパティ デコレータはメソッドをプロパティに変換して呼び出すことができます。Python の黒魔術 @プロパティ デコレータの使用スキル分析を見てみましょう
@ 属性は何に使用されますか?表面的には、メソッドは属性としてアクセスされているように見えます。
上記のコード
class Circle(object): def __init__(self, radius): self.radius = radius @property def area(self): return 3.14 * self.radius ** 2 c = Circle(4) print c.radius print c.area
ご覧のとおり、エリアはメソッド形式で定義されていますが、 @property を追加すると、プロパティとして c.area に直接アクセスできます。
ここで疑問が生じます。c.area が呼び出されるたびに、計算が 1 回行われます。CPU の無駄です。どうすれば 1 回だけ計算できるでしょうか?これは怠惰の性質です。
class lazy(object): def __init__(self, func): self.func = func def __get__(self, instance, cls): val = self.func(instance) setattr(instance, self.func.__name__, val) return val class Circle(object): def __init__(self, radius): self.radius = radius @lazy def area(self): print 'evalute' return 3.14 * self.radius ** 2 c = Circle(4) print c.radius print c.area print c.area print c.area
ご覧のとおり、「evalute」は 1 回しか出力されないため、@Lazy のメカニズムをよく理解しておく必要があります。
ここでは、遅延クラスには、記述子であることを示す __get__ メソッドがあります。c.area が初めて実行されるとき、順序の問題により、最初に Ç.__dict__ で検索されます。見つからない場合は、クラス空間に移動して見つけてください。クラス サークル内には area() メソッドがあるため、__get__ によってインターセプトされます。
__get__ では、インスタンスのregion() メソッドを呼び出して結果を計算し、同じ名前の属性をインスタンスに動的に追加して結果をそれに割り当てます。つまり、それを Ç に追加します。 __ 辞書__。
c.area を再度実行するときは、まず Ç.__ dict__ に移動してそれを見つけます。これはこの時点ですでにそこにあるため、area () メソッドと __get__ を経由しません。
注意
次のコード シナリオに注意してください。
コード スニペット 1:
class Parrot(object): def __init__(self): self._voltage = 100000 @property def voltage(self): """Get the current voltage.""" return self._voltage if __name__ == "__main__": # instance p = Parrot() # similarly invoke "getter" via @property print p.voltage # update, similarly invoke "setter" p.voltage = 12
コード スニペット 2:
class Parrot: def __init__(self): self._voltage = 100000 @property def voltage(self): """Get the current voltage.""" return self._voltage if __name__ == "__main__": # instance p = Parrot() # similarly invoke "getter" via @property print p.voltage # update, similarly invoke "setter" p.voltage = 12
コード 1 、2 の違いは
class Parrot (object):
Python2 でテストを個別に実行します
フラグメント 1: 予想されるエラー メッセージ AttributeError: Unable toプロパティを設定するよう求められます
フラグメント 2: 正しい操作
Python2 ドキュメントを参照してください。@property は読み取り専用属性を提供します。上記のコードは、対応する @voltage.setter を提供しません。フラグメント 2 のコードが実行エラーを表示するのは当然です。python2 ドキュメントには次の情報があります:
BIF:
property([fget[,fset[, fdel[,doc]]])
新しいスタイル クラス (Object から派生したクラス) の属性プロパティを返します。
Python2 では、組み込み型オブジェクトがデフォルトの基本クラスではないことが判明しました。クラスを定義するときに明確な説明がない場合 (コード スニペット 2)、定義した Parrot (コード スニペット 2) ) は Object を継承しません
オブジェクト クラスは、必要な @property 関数を提供するだけです。ドキュメントには次の情報があります:
新しいスタイルのレッスン
任意のクラスこれは object から継承します。これには、list や dict などのすべての組み込み型が含まれます。新しいスタイルのクラスのみが、__slots__、記述子、属性、__getattribute__() などの Python の新しい汎用機能を使用できます。
同時に、次のメソッドを通じて検証することもできます。
class A: pass >>type(A) <type 'classobj'>
class A(object): pass >>type(A) <type 'type'>
返された
考慮するために移行期間中の Python バージョンのコードの互換性について質問です。クラス ファイルを定義するときは、良い習慣としてオブジェクトを明示的に定義する必要があると思います。
最終的なコードは次のようになります:
ああ、以上がPython での @property デコレーターの注意が必要な使用法 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。