描述符
一、概念:
Python 中,通过使用描述符,可以让程序在引用一个对象属性时自定义要完成的工作。
本质上看,描述符就是一个类,只不过它定义了另一个类中属性的访问方式。
换句话说,一个类可以将属性全权委托给描述符类。
描述符类基于以下3个特殊方法:
♦ __set__ (self, instance, value) 设置属性调用
♦ __get__(self,instance, owner) 访问属性调用
♦ __delete__(self, instance) 对属性调用del 时将调用这一方法
二、描述符分两种
①数据描述符:至少实现了 __get__()和__set__()
class Foo:
def __set__(selfsself,instance, value):
print("set")
def __get__(self, instance, owner):
print("get")
②非数据描述符:没有实现__set__()
class Foo:
def __get__(self, instance, owner):
print("get")
实例:
class Foo:
def __get__(self, instance, owner): #这里的instance是实例对象b1,owner是类Bar
print("===>get方法")
return instance.__dict__['x']
def __set__(self, instance, value): #这里的instance是实例对象b1,value是传入的值
print("===>set方法")
instance.__dict__['x'] = value
def __delete__(self, instance):
print("===>delete方法")
instance.__dict__.pop('x')
class Bar:
x = Foo() #将x 全权给Foo类代理,此时 x 就是描述符
def __init__(self, n):
self.x = n
b1 = Bar(10)
print(b1.__dict__)
print(b1.x)
del b1.x
print(b1.__dict__)
b1.x = 222222222
print(b1.__dict__)
b1.y = 2222
print(b1.__dict__)
三、描述符优先级
类属性 > 数据描述符 > 实例属性 > 非数据属性 > 找不到的属性触发__getattr__
class Foo:
def __get__(self, instance, owner): #这里的instance是实例对象b1,owner是类Bar
print("===>get方法")
# return instance.__dict__['x']
def __set__(self, instance, value): #这里的instance是实例对象b1,value是传入的值
print("===>set方法")
# instance.__dict__['x'] = value
def __delete__(self, instance):
print("===>delete方法")
# instance.__dict__.pop('x')
class Bar:
x = Foo()
def __init__(self, n):
self.x = n
b1 = Bar(10)
print(Bar.__dict__) #这里打印字典看出:x 是一个对象
Bar.x = 10
print(Bar.x)
print(Bar.__dict__) #当Bar.x为x后,直接覆盖了描述符的操作

class Foo:
def __get__(self, instance, owner): #这里的instance是实例对象b1,owner是类Bar
print("===>get方法")
# return instance.__dict__['x']
def __set__(self, instance, value): #这里的instance是实例对象b1,value是传入的值
print("===>set方法")
# instance.__dict__['x'] = value
def __delete__(self, instance):
print("===>delete方法")
# instance.__dict__.pop('x')
class Bar:
x = Foo()
def __init__(self, n):
self.x = n
b1 = Bar(10)
b1.x = 10 #可以看出。用实例为变量赋值时,直接触发数据描述符
print(b1.__dict__)
class Foo:
def __get__(self, instance, owner): #这里的instance是实例对象b1,owner是类Bar
print("===>get方法")
# return instance.__dict__['x']
# def __set__(self, instance, value): #这里的instance是实例对象b1,value是传入的值
# print("===>set方法")
# # instance.__dict__['x'] = value
# def __delete__(self, instance):
print("===>delete方法")
# instance.__dict__.pop('x')
class Bar:
x = Foo()
def __init__(self, n):
self.x = n
b1 = Bar(10)
b1.x = 10 #可以看出。用实例为变量赋值时,没有触发非数据描述符
print(b1.__dict__)
class Foo:
def __get__(self, instance, owner): #这里的instance是实例对象b1,owner是类Bar
print("===>get方法")
# return instance.__dict__['x']
# def __set__(self, instance, value): #这里的instance是实例对象b1,value是传入的值
# print("===>set方法")
# # instance.__dict__['x'] = value
# def __delete__(self, instance):
print("===>delete方法")
# instance.__dict__.pop('x')
class Bar:
x = Foo()
def __init__(self, n):
self.x = n
def __getattr__(self, item):
print("qaq")
b1 = Bar(10)
b1.yyyy #当查找的属性不存在时
一个奋斗中的产品小白

浙公网安备 33010602011771号