# ############### 定义 ############### 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 方法
from datetime import date, datetime 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
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/9388065.html