当前位置 : 主页 > 编程语言 > python >

python属性描述符和属性查找过程

来源:互联网 收集:自由互联 发布时间:2022-06-15
# ############### 定义 ############### 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 方法


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


上一篇:python面向对象之依赖注入
下一篇:没有了
网友评论