描述符(__get__,__set__,__delete__)
4 注意事项: 一 描述符本身应该定义成新式类,被代理的类也应该是新式类 二 必须把描述符定义成这个类的类属性,不能为定义到构造函数中 三 要严格遵循该优先级,优先级由高到底分别是 1.类属性 2.数据描述符 3.实例属性 4.非数据描述符 5.找不到的属性触发__getattr__()
1 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议 __get__():调用一个属性时,触发 __set__():为一个属性赋值时,触发 __delete__():采用del删除属性时,触发
class Foo: #在python3中Foo是新式类,它实现了三种方法,这个类就被称作一个描述符 def __get__(self, instance, owner): pass def __set__(self, instance, value): pass def __delete__(self, instance): pass 定义一个描述符
2 描述符是干什么的:描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中) class Foo: def __get__(self, instance, owner): print(‘触发get‘) def __set__(self, instance, value): print(‘触发set‘) def __delete__(self, instance): print(‘触发delete‘) #包含这三个方法的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法 f1=Foo() f1.name=‘egon‘ f1.name del f1.name #疑问:何时,何地,会触发这
#描述符Str class Str: def __get__(self, instance, owner): print(‘Str调用‘) def __set__(self, instance, value): print(‘Str设置...‘) def __delete__(self, instance): print(‘Str删除...‘) #描述符Int class Int: def __get__(self, instance, owner): print(‘Int调用‘) def __set__(self, instance, value): print(‘Int设置...‘) def __delete__(self, instance): print(‘Int删除...‘) class People: name=Str() age=Int() def __init__(self,name,age): #name被Str类代理,age被Int类代理, self.name=name self.age=age #何地?:定义成另外一个类的类属性 #何时?:且看下列演示 p1=People(‘alex‘,18) #描述符Str的使用 p1.name p1.name=‘egon‘ del p1.name #描述符Int的使用 p1.age p1.age=18 del p1.age #我们来瞅瞅到底发生了什么 print(p1.__dict__) print(People.__dict__) #补充 print(type(p1) == People) #type(obj)其实是查看obj是由哪个类实例化来的 print(type(p1).__dict__ == People.__dict__) # 描述符应用之何时?何地?三个方法的执行\ # 执行顺序 # Str设置... # Int设置... # Str调用 # Str设置... # Str删除... # Int调用 # Int设置... # Int删除... # {} # {‘__module__‘: ‘__main__‘, ‘name‘: <__main__.Str object at 0x00000177DAFD5048>, ‘age‘: <__main__.Int object at 0x00000177DAFD5080>, ‘__init__‘: <function People.__init__ at 0x00000177DAFCAEA0>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘People‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘People‘ objects>, ‘__doc__‘: None} # True # True
二 .描述符分两种
1. 数据描述符:至少实现了__get__()和__set__()
一 数据描述符:至少实现了__get__()和__set__() 1 class Foo: 2 def __set__(self, instance, value): 3 print(‘set‘) 4 def __get__(self, instance, owner): 5 print(‘get‘)
# 实例属性是低于 数据描述符 所以优先找的是描述符属性 优先级 class Foo: def __set__(self, instance, value): print(‘set‘) print(value) def __get__(self, instance, owner): print(‘get‘) print(owner)class Per(object): name=Foo() def __init__(self,name): self.name=name def aa(self): print(self.name) f=Per("李四")f.namef.aa()# # get# <class ‘__main__.Per‘># get# <class ‘__main__.Per‘># None
2. 非数据描述符:没有实现__set__()
1 class Foo: 2 def __get__(self, instance, owner): 3 print(‘get‘)
# 实例属性是高于 非数据描述符 所以优先找的是实例属性 这就是优先级class Foo: def __get__(self, instance, owner): print(‘get‘)class Per(object): name=Foo() def __init__(self,name): self.name=name def aa(self): print(self.name)f=Per("李四")print(f.name)print(f.__dict__)print(Per.__dict__) # 李四# {‘name‘: ‘李四‘}# {‘__module__‘: ‘__main__‘, ‘name‘: <__main__.Foo object at 0x00000268526C8860>, ‘__init__‘: <function Per.__init__ at 0x00000268526CABF8>, ‘aa‘: <function Per.aa at 0x00000268526CAD08>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Per‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Per‘ objects>, ‘__doc__‘: None}
原文地址:https://www.cnblogs.com/Sup-to/p/11087506.html
时间: 2024-10-08 17:31:50