python@propertyの使用
2933 ワード
引用-廖雪峰
背景
アトリビュートを設定するときは、アトリビュートを直接露出することができます.これは簡単ですが、アトリビュート値を勝手に変更することになります.
上記の値が勝手に変更されないように、関数を増やして判断し、属性値が有効かどうかを確認することができます.
しかし、上記の使い方は複雑ですが、pythonはこの機能を実現する方法がありますか?はい、Python内蔵の
読み取り専用プロパティを定義することもできます.getterメソッドのみを定義し、setterメソッドを定義しないのは読み取り専用プロパティです.
まとめ
背景
アトリビュートを設定するときは、アトリビュートを直接露出することができます.これは簡単ですが、アトリビュート値を勝手に変更することになります.
class Student(object):
def __init__(self):
self.score = 60
In [13]: student = Student()
In [15]: student.score
Out[15]: 60
In [16]: student.score=101
In [17]: student.score
Out[17]: 101
上記の値が勝手に変更されないように、関数を増やして判断し、属性値が有効かどうかを確認することができます.
class Student(object):
def __init__(self):
self.score = 60
def get_score(self):
return self.score
def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score %s must be an integer!' % value)
if value < 0 or value > 100:
raise ValueError('score %s must between 0 ~ 100!' % value)
self.score = value
In [2]: student = Student()
In [3]: student.score
Out[3]: 60
In [4]: student.get_score()
Out[4]: 60
In [6]: student.set_score(95)
In [7]: student.score
Out[7]: 95
In [8]: student.get_score()
Out[8]: 95
In [9]: student.set_score(9.9)
---------------------------------------------------------------------------
... ...
ValueError: score 9.9 must be an integer!
In [10]: student.set_score(101)
---------------------------------------------------------------------------
... ...
ValueError: score 101 must between 0 ~ 100!
しかし、上記の使い方は複雑ですが、pythonはこの機能を実現する方法がありますか?はい、Python内蔵の
@property
装飾器です@property
デコレーションを使用class Student(object):
def __init__(self):
self.score = 60
@property
def student_score(self): # student_score score
return self.score
@student_score.setter
def student_score(self, value):
if not isinstance(value, int):
raise ValueError('score %s must be an integer!' % value)
if value < 0 or value > 100:
raise ValueError('score %s must between 0 ~ 100!' % value)
self.score = value
@property
を加えて、getterメソッドを属性にします.@property
自体は、setterメソッドを属性付与に変更する役割を果たす別の装飾器@student_score.setter
を作成し、制御可能な(メソッドが属性になる)操作を有している.In [5]: student = Student()
In [6]: student.score
Out[6]: 60
In [7]: student.student_score
Out[7]: 60
In [8]: student.student_score = 95
In [9]: student.score
Out[9]: 95
In [10]: student.student_score
Out[10]: 95
In [11]: student.student_score = 9.5
---------------------------------------------------------------------------
... ...
ValueError: score 9.5 must be an integer!
In [12]: student.student_score = 101
---------------------------------------------------------------------------
... ...
ValueError: score 101 must between 0 ~ 100!
読み取り専用プロパティを定義することもできます.getterメソッドのみを定義し、setterメソッドを定義しないのは読み取り専用プロパティです.
まとめ
@property
はクラスの定義に広く適用され、呼び出し者に短いコードを書かせるとともに、パラメータの必要なチェックを保証することができ、プログラムの実行時にエラーの可能性を減らすことができる.