# ############### 定义 ############### class Goods(object): @property def price(self): print '@property' @price.setter def price(self, value): print '@price.setter' @price.deleter def price(self): print '@price.deleter' # ############### 调
class Goods(object):
@property
def price(self):
print '@property'
@price.setter
def price(self, value):
print '@price.setter'
@price.deleter
def price(self):
print '@price.deleter'
# ############### 调用 ###############
obj = Goods()
obj.price # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123 # 自动执行 @price.setter 修饰的 price 方法,并将 123 赋值给方法的参数
del obj.price # 自动执行 @price.deleter 修饰的 price 方法
import numbers
import string
#数据描述符
class IntField:
#数据描述符
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
if not isinstance(value, numbers.Integral):
raise ValueError("int value need")
if value < 0:
raise ValueError("positive value need")
self.value = value
def __delete__(self, instance):
pass
#非数据描述符
class NonDataIntField:
#非数据属性描述符
def __get__(self, instance, owner):
return self.value
第一种情况:
class User:age = IntField()
if __name__ == "__main__":
user = User()
user.age = 30
print (user.age)
print (user.__dict__)//此处输出的是{}
user.__dict__['age'] = '29'
print (user.age)
print (user.__dict__['age'])
输出:
30
{}
30
29
print (user.__dict__) 是 {}呢?
原理如下:
如果user是某个类的实例,那么user.age(以及等价的getattr(user,’age’))
首先调用__getattribute__。如果类定义了__getattr__方法,
那么在__getattribute__抛出 AttributeError 的时候就会调用到__getattr__,
而对于描述符(__get__)的调用,则是发生在__getattribute__内部的。
user = User(), 那么user.age 顺序如下:
(1)(类和基类)如果“age”是出现在User类或其基类的__dict__中, 且age是data descriptor(数据描述符IntField), 那么调用其__get__方法, 否则
(2)如果“age”出现在user对象的__dict__中, 那么直接返回 obj.__dict__[‘age’], 否则
(3)如果“age”出现在User类或其基类的__dict__中
(3.1)如果age是non-data descriptor(非数据描述符),那么调用其非数据描述符(NonDataIntField)__get__方法, 否则
(3.2)返回 __dict__[‘age’]
(4)如果User类有__getattr__方法,调用__getattr__方法,否则
(5)抛出AttributeError