1 描述符是什么:描述符本質就是一個新式類,在這個新式類中,至少實現了__get__(),set(),delete()中的一個,這也被稱為描述符協議
get():調用一個屬性時,觸發
set():為一個屬性賦值時,觸發
delete():采用del刪除屬性時,觸發
class Foo:
def __get__(self,instance,owner):
print("=====>get方法")
def __set__(self,instance,value):
print("=====>set方法",instance, value)
instance.__dict__['x'] = value
def __delete__(self,instance):
print("=====>set方法")
class Bar:
x = Foo() #描述符,對x對象屬性的調用去找Foo對象
def __init__(self,n):
self.x = n
b1 = Bar(10) #首先觸發Bar的__init__函數, 傳入x參數, x參數被Foo代理,
# 觸發Foo的x方法,觸發Foo的set方法
print(b1.__dict__)
print(Bar.__dict__)
b1.x = 11111111
print(b1.__dict__)
>>>
=====>set方法 <__main__.Bar object at 0x01F91370> 10
{'x': 10}
{'__module__': '__main__', 'x': <__main__.Foo object at 0x01F91250>, '__init__': <function Bar.__init__ at 0x01EBCC48>, '__dict__': <attribute '__dict__' of 'Bar' objects>, '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None}
=====>set方法 <__main__.Bar object at 0x01F91370> 11111111
{'x': 11111111}
- 注意事項:
一 描述符本身應該定義成新式類,被代理的類也應該是新式類
二 必須把描述符定義成這個類的類屬性,不能為定義到構造函數中
三 要嚴格遵循該優先級,優先級由高到底分別是 - 類屬性 (類屬性高於數據描述符)
- 數據描述符 (get, set)
- 實例屬性
- 非數據描述符(沒有set方法)
- 找不到的屬性觸發__getattr__()