使用Property管理屬性
python提供了一種友好的getter、setter、deleter類方法的屬性管理工具:property。
property()是一個內建函式,它返回一個Property物件,它的用法很簡單,將getter、setter、deleter三個方法作為它的引數即可,這些引數都是可選的。
property_obj = property(getter,setter,deleter,doc)
通過這個Property物件可以智慧地判斷是getter操作、setter操作還是delete操作,見下面的示例。
唯一需要注意的是使用Property管理時,setter、deleter方法不要返回任何值,也就是說讓它返回None(這是預設的),getter方法返回所取屬性的值。
例如,對於Person的name屬性來說:
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
def set_name(self, name): self._name = name
def get_name(self): return self._name
def del_name(self): del self._name
name = property(get_name, set_name, del_name)
if __name__ == "__main__":
p1 = Person("malongshuai", 23)
print(p1.name) # 自動呼叫get_name
p1.name = "malong" # 自動呼叫set_name
print(p1.name) # 自動呼叫get_name
del p1.name # 自動呼叫del_name
print(p1.name) # 自動呼叫get_name,將報錯
注意上面**property物件名為name,和物件屬性”_name”是不同的,如果相同,則會出現無限遞迴問題**。
通過name這個property物件,就可以智慧地判斷是getter操作、setter操作還是deleter操作。
property結合裝飾器也一樣方便,這正是以前版本的python所常用的功能。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@property # 等價於 Name = property(Name)
def Name(self): return self.name
@Name.setter # 等價於 Name = Name.setter(Name)
def Name(self, name): self.name = name
@Name.deleter # 等價於 Name = Name.deleter(Name)
def Name(self): del self.name
if __name__ == "__main__":
p1 = Person("malongshuai", 23)
print(p1.Name) # 自動呼叫get_name
p1.Name = "malong" # 自動呼叫set_name
print(p1.Name) # 自動呼叫get_name
del p1.Name # 自動呼叫del_name
至於選擇使用裝飾器結合Property還是直接使用property的內建函式,自行選擇,並沒有什麼區別。
通過Property,還可以返回計算後的值。
class A():
def __init__(self, value):
self.value = value
def two_time(self, value):
self.value = self.value * 2
def get_value(self):
return self.value
Value = property(get_value, two_time)
if __name__ == "__main__":
a = A(23)
print(a.Value)
a.Value = 33
print(a.Value)
Property物件的屬性
先看看Property的定義:
class property(object)
| property(fget=None, fset=None, fdel=None, doc=None)
|
| Property attribute.
|
| fget
| function to be used for getting an attribute value
| fset
| function to be used for setting an attribute value
| fdel
| function to be used for del`ing an attribute
| doc
| docstring
這些無需解釋。
再看下property的屬性:
>>> property.__dict__.keys()
dict_keys([`__getattribute__`, `__get__`, `__set__`, `__delete__`, `__init__`, `__new__`, `getter`, `setter`, `deleter`, `fget`, `fset`, `fdel`, `__doc__`, `__isabstractmethod__`])
關注一下它的getter、setter、deleter方法,在前面property結合裝飾器的示例中已經使用到了這幾個函式。:
deleter(...)
Descriptor to change the deleter on a property.
getter(...)
Descriptor to change the getter on a property.
setter(...)
Descriptor to change the setter on a property.
看方法的文件說明是設定Property物件上的getter、setter、deleter方法,這句話結合前面的”property+裝飾器”的示例很容易理解和使用。