概念
可以描述一个属性操作的对象
定义
定义方式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