ホームページ  >  記事  >  バックエンド開発  >  Python プログラミングにおける @property デコレーターの使用法を説明する例

Python プログラミングにおける @property デコレーターの使用法を説明する例

WBOY
WBOYオリジナル
2016-07-21 14:53:191113ブラウズ

価値と割り当て

リーリー


Access クラスには 2 つのメンバー変数 name と age があります。クラスメンバ変数に対する外部操作には主に値の取得と代入が含まれます。単純な値の演算は x=object.var で、単純な代入演算は object.var=value です。

リーリー

ゲッターとセッターを使用する
上記の単純な値の取得と代入の操作では要件を満たせない場合があります。たとえば、Access の年齢範囲を制限したい場合、上記の単純な割り当て操作を使用するだけでは要件を満たしません。ゲッターとセッターはそのような要件を実装します。

リーリー

setAge 関数を呼び出して、変数 _age の値の範囲を 30 未満に制限します。

リーリー

プロパティを使用する
プロパティの定義は次のとおりです:
このうち、fget は値関数、fset は代入関数、fdel は削除関数です。プロパティを使用すると、メンバー変数に対する前述の値制限も実装されます。

リーリー

上記の定義後、年齢は単純な値の取得と代入の操作のように操作できます。たとえば、

リーリー

@propertyを使用してください
@property を使用することでも上記のクラスの定義を実現できます。

リーリー

使用例:

リーリー

Python2 と Python3 でのプロパティの使用の違い
上記のプロパティの例は、Python3 環境で有効です。 Python2ではプロパティを使用する場合、クラス定義はオブジェクトを継承する必要があります。それ以外の場合、プロパティ割り当て操作は使用できません。

Python2でプロパティを使用する正しい方法:

リーリー
例: クイックコードリファクタリング
昔、Python プログラマーのアリスは、お金を表すクラスを作成したいと考えていました。彼女の最初の実装はおそらく次のとおりです:
リーリー

このクラスは後に Python ライブラリにパッケージ化され、さまざまなアプリケーションでゆっくりと使用されるようになりました。たとえば、別のチームの Python プログラマーである Bob は、Money クラスを次のように使用します。

リーリー

この方法で使用することに問題はありませんが、コードの保守性に問題が生じます。発見しましたか?

数ヶ月後、あるいは数年後。アリスは、Money クラスの内部実装をリファクタリングして、ドルとセントを記録せず、セントのみを記録したいと考えています。そうすることで、特定の操作がはるかに簡単になるためです。彼女が行う可能性のある変化は次のとおりです:

リーリー

この変更により 1 つの結果がもたらされます。Money クラスを参照するコードのすべての行を調整する必要があります。幸運なことに、あなたがこのすべてのコードの管理者であり、自分で直接リファクタリングする必要がある場合もあります。しかし、アリスの状況はそれほど良くはありませんでした。多くのチームが彼女のコードを再利用しました。したがって、彼女は彼らのコードベースと自分の変更を調整する必要があり、おそらく特に苦痛で長い正式な非推奨プロセスを経ることさえあるでしょう。

幸いなことに、Alice は、この頭痛の種を回避するためのより良い解決策を知っています。それは、Python の組み込みプロパティ デコレーターを使用することです。 @property は通常、Python メソッドで使用され、属性へのアクセスを効果的にメソッド呼び出しに変えることができます。たとえば、Money クラスを少し脇に置き、人間を表す Person クラスがあると仮定します。

リーリー

以前使用していたツールに問題があったため、コードスタイルが異なります。 —アールグレイ

full_name メソッドに注意してください。メソッドの宣言は、def ステートメントの上に @property で装飾されている点を除き、何も変わりません。ただし、これにより Person オブジェクトの動作方法が変わります。

リーリー

full_name はメソッドとして定義されていますが、変数属性を通じてアクセスできることがわかりました。コードの最後の行には () 演算子がありません。full_name メソッドを呼び出しているわけではありません。私たちが行ったことは、いわば、ある種の動的プロパティを作成したことです。

この記事の Money クラスに戻り、Alice はそれに次の変更を加えました。

リーリー
@property デコレータを使用して $ プロパティのゲッターを定義することに加えて、Alice は @dollars.setter を使用してセッターも作成します。アリスは、cents 属性に対しても同様の処理を実行しました。

それでは、Bob のコードに対応するどのような変更を加えるべきでしょうか?まったく変える必要はありません!

リーリー
実際、Money クラスを使用するすべてのコードを変更する必要はありません。ボブは、アリスがクラスからドルとセントの属性を削除したことを知りませんし、気にも留めません。彼のコードは以前と同じように正常に実行されます。変更された唯一のコードは、Money クラス自体です。

Python でのデコレーターの処理方法により、クラス内で単純な属性を自由に使用できます。状態の管理方法を変更するクラスを作成する場合、@property デコレーターを使用してそのクラス (およびそのクラスのみ) を自信を持って変更できます。これは双方にとって有利なアプローチです。対照的に、Java などの言語では、プログラマはプロパティにアクセスするためのメソッド (getDollars や setCents など) を積極的に定義する必要があります。

最後に、注意事項: このメソッドは、他のプログラマーやチームによって再利用されるコードにとって最も重要です。管理するアプリケーションで Money のようなクラスを作成するだけだと仮定すると、Money のインターフェイスを変更する場合は、独自のコードをリファクタリングするだけで済みます。この場合、上記のように @property デコレータを使用する必要はありません。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。