Python描述符descriptor使用原理解析
描述符(descriptor)是實(shí)現(xiàn)了__get__、__set__、__del__方法的類(lèi),進(jìn)一步可以細(xì)分為兩類(lèi):
數(shù)據(jù)描述符:實(shí)現(xiàn)了__get__和__set__
非數(shù)據(jù)描述符:沒(méi)有實(shí)現(xiàn)__set__
描述符在類(lèi)的屬性調(diào)用中起著很重要的作用,類(lèi)在調(diào)用屬性時(shí),遵守兩個(gè)規(guī)則:
按照實(shí)例屬性、類(lèi)屬性的順序選擇屬性,即實(shí)例屬性?xún)?yōu)先于類(lèi)屬性
如果在類(lèi)屬性中發(fā)現(xiàn)同名的數(shù)據(jù)描述符,那么該描述符會(huì)優(yōu)先于實(shí)例屬性
非數(shù)據(jù)描述符會(huì)被實(shí)例屬性覆蓋
class A:
def __get__(self, obj, cls):
return f"{obj}: get"
class B:
value = A()
def __init__(self):
self.value = 4
def main():
g = B()
print(g.value)
print(g.__dict__)
if __name__ == "__main__":
main()
輸出結(jié)果
4
{'value': 4}
數(shù)據(jù)描述符優(yōu)于實(shí)例屬性
class A:
def __get__(self, obj, cls):
return f"{obj}: get"
def __set__(self, obj, value):
print(f"{obj}: set, {value}")
class B:
value = A()
def __init__(self):
self.value = 4
def main():
g = B()
print(g.value)
print(g.__dict__)
if __name__ == "__main__":
main()
輸出結(jié)果
<__main__.B object at 0x000001165EB85898>: set, 4
<__main__.B object at 0x000001165EB85898>: get
{}
從上述兩個(gè)例子中可以看到,類(lèi)B的value屬性是一個(gè)描述符,當(dāng)value屬性是一個(gè)數(shù)據(jù)描述符時(shí),它屏蔽了實(shí)例的同名屬性value,實(shí)例對(duì)value屬性的讀取與賦值都會(huì)直接被轉(zhuǎn)移到類(lèi)屬性value上。
使用描述符實(shí)現(xiàn)類(lèi)的靜態(tài)方法與類(lèi)方法
from functools import partial
class Staticmethod:
def __init__(self, method):
self.method = method
def __get__(self, obj, cls):
return self.method
class Classmethod:
def __init__(self, method):
self.method = method
def __get__(self, obj, cls):
return partial(self.method, cls)
class A:
@Staticmethod
def f(self):
print(f"I'm method f, the value is {self}")
@Classmethod
def c(self):
print(f"my class is {self}")
a = A()
a.f(23)
A.f(23)
a.c()
A.c()
輸出結(jié)果
I'm method f, the value is 23
I'm method f, the value is 23
my class is <class '__main__.A'>
my class is <class '__main__.A'>
靜態(tài)方法與類(lèi)方法統(tǒng)一了類(lèi)屬性的兩種引用方式。這種統(tǒng)一的過(guò)程可以使用描述符修改屬性訪問(wèn)的默認(rèn)方式實(shí)現(xiàn)。靜態(tài)方法限制實(shí)例的默認(rèn)綁定,將方法當(dāng)做普通函數(shù)使用;類(lèi)方法始終將類(lèi)作為第一個(gè)參數(shù)傳入,上述的partial將類(lèi)固定為方法的第一個(gè)參數(shù)。
總結(jié)
- 描述符是實(shí)現(xiàn)了__get__、__set__、__del__等特殊方法的類(lèi),在屬性訪問(wèn)時(shí)起著很大的作用。
- 數(shù)據(jù)描述符會(huì)覆蓋同名的實(shí)例屬性,通過(guò)使用數(shù)據(jù)描述符,達(dá)到通過(guò)實(shí)例修改類(lèi)變量的目的。
- 描述符用于修改屬性的默認(rèn)訪問(wèn)方式,借此可以實(shí)現(xiàn)類(lèi)方法與靜態(tài)方法。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python實(shí)現(xiàn)跳表SkipList的示例代碼
這篇文章主要介紹了python實(shí)現(xiàn)跳表SkipList的示例代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07
基于PyQt5實(shí)現(xiàn)一個(gè)串口接數(shù)據(jù)波形顯示工具
這篇文章主要為大家詳細(xì)介紹了如何利用PyQt5實(shí)現(xiàn)一個(gè)串口接數(shù)據(jù)波形顯示工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-01-01
Pytorch GPU內(nèi)存占用很高,但是利用率很低如何解決
這篇文章主要介紹了Pytorch GPU內(nèi)存占用很高,但是利用率很低的原因及解決方法,具有很好的參考價(jià)值,希望對(duì)大家 有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
python優(yōu)化測(cè)試穩(wěn)定性的失敗重試工具pytest-rerunfailures詳解
筆者在執(zhí)行自動(dòng)化測(cè)試用例時(shí),會(huì)發(fā)現(xiàn)有時(shí)候用例失敗并非代碼問(wèn)題,而是由于服務(wù)正在發(fā)版,導(dǎo)致請(qǐng)求失敗,從而降低了自動(dòng)化用例的穩(wěn)定性,那該如何增加失敗重試機(jī)制呢?帶著問(wèn)題我們一起探索2023-10-10
python?gravis庫(kù)實(shí)現(xiàn)圖形數(shù)據(jù)可視化實(shí)例探索
這篇文章主要為大家介紹了python?gravis庫(kù)實(shí)現(xiàn)圖形數(shù)據(jù)可視化實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-02-02
python隨機(jī)生成大小寫(xiě)字母數(shù)字混合密碼(僅20行代碼)
這篇文章主要介紹了python隨機(jī)生成大小寫(xiě)字母數(shù)字混合密碼,主要是利用random模塊隨機(jī)生成數(shù)字,大小寫(xiě)字母,通過(guò)循環(huán)次數(shù)來(lái)實(shí)現(xiàn)此功能,需要的朋友可以參考下2020-02-02

