概念
可以描述一個屬性操作的對象
定義
定義方式1 property
class Person():
def __init__(self):
self.__age = 10
def get_age(self):
return self.__age
def set_age(self, value):
if value < 0:
value = 0
self.__age = value
def del_age(self):
del self.__age
age = property(get_age, set_age, del_age)
p = Person()
# p.set_age(-10)
# print(p.get_age())
p.age = 19
print(p.age)
del p.age
19
定義方式2
class Age():
def __get__(self, instance, owner):
print('get')
def __set__(self, instance, value):
print('set')
def __delete__(self, instance):
print('delete')
class Person():
age = Age()
p = Person()
p.age = 19
print(p.age)
del p.age
set
get
None
delete
調用細節
使用實例進行調用。
只在新式類有效,在經典類不生效。
方法攔截
- 一個實例屬性的正常訪問順序:
- 實例對象自身的 __dict__ 字典
- 對應類對象的 __dict__ 字典
- 如果有父類,會再往上層的 __dict__ 字典中檢測
- 如果沒找到,又定義了 __getattr__ 方法,就會調用這個方法
將描述器的__get__方法給嵌入到查找機制當中,就是通過__getattribute__ 來實現
調用優先級
資料描述器:實現了 get set
非資料描述器:僅實現了 get
優先級:資料描述器 > 實例屬性 > 非資料描述器
class Age():
def __get__(self, instance, owner):
print('get')
# def __set__(self, instance, value):
# print('set')
# def __delete__(self, instance):
# print('delete')
class Person():
age = Age()
def __init__(self):
self.age = 10
p = Person()
p.age = 19
print(p.age)
print(p.__dict__)
19
{‘age’: 19}
數據存儲問題
class Age():
def __get__(self, instance, owner):
print('get')
return instance.v
def __set__(self, instance, value):
print('set', self, instance, value)
instance.v = value
def __delete__(self, instance):
print('delete')
del instance.v
class Person():
age = Age()
p = Person()
p.age = 19
p2 = Person()
p2.age = 11
print(p.age)
print(p2.age)
set <main.Age object at 0x03855990> <main.Person object at 0x04259850> 19
set <main.Age object at 0x03855990> <main.Person object at 0x04259DD0> 11
get
19
get
11