輕松理解Python 中的 descriptor
定義
通常,一個(gè) descriptor 是具有“綁定行為”的對(duì)象屬性。所綁定行為可通過 descriptor 協(xié)議被自定義的 __get__() , __set__() 和 __delete__() 方法重寫。如果一個(gè)對(duì)象的上述三個(gè)方法任意一個(gè)被重寫,則就可被稱為 descriptor。
屬性的默認(rèn)操作是從對(duì)象字典中獲取、設(shè)置和刪除一個(gè)屬性。例如,a.x 有一個(gè)查找鏈,先 a.__dict__['x'] ,若沒有則 type(a).__dict__['x'] ,若沒有增往上查找父類直到元類。如果查找鏈中,對(duì)象被定義了 descriptor 方法,Python 就會(huì)覆蓋默認(rèn)行為。
Descriptor 是一個(gè)強(qiáng)大的工具,雖然開發(fā)者不常接觸到它,但它其實(shí)就是類、屬性、函數(shù)、方法、靜態(tài)方法、類方法以及 super() 背后的運(yùn)行機(jī)制。
Descriptor 協(xié)議
三個(gè)方法原型如下所示:
descr.__get__(self, obj, type=None) --> value descr.__set__(self, obj, value) --> None descr.__delete__(self, obj) --> None
數(shù)據(jù) descriptor 是同時(shí)具有 __get__() 和 __set__() 方法的對(duì)象,若只有 __get__() 方法,則為非數(shù)據(jù) descriptor。如果實(shí)例字典中有和數(shù)據(jù) descriptor 同名的入口,則數(shù)據(jù) descriptor 優(yōu)先級(jí)更高。相反,非數(shù)據(jù) descriptor 優(yōu)先級(jí)低。
讓 __set__() 方法拋出異常,就能創(chuàng)建一個(gè)只讀數(shù)據(jù) descriptor。
調(diào)用 descriptor
descriptor 可以直接通過方法名調(diào)用。例如, d.__get__(obj) 。
而通過訪問對(duì)象屬性,自動(dòng)調(diào)用 descriptor 才是更通用的做法。例如,如果 d 定義了方法 __get__() ,則 obj.d 會(huì)調(diào)用 d.__get__(obj) 。
對(duì)于對(duì)象, b.x 會(huì)被轉(zhuǎn)換成 type(b).__dict__['x'].__get__(b, type(b)) 。而對(duì)于類(是的,類也可以調(diào)用), B.x 會(huì)被轉(zhuǎn)換成 B.__dict__['x'].__get__(None, B) 。
Descriptor 例子
class RevealAccess(object):
"""A data descriptor that sets and returns values
normally and prints a message logging their access.
"""
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
print('Retrieving', self.name)
return self.val
def __set__(self, obj, val):
print('Updating', self.name)
self.val = val
>>> class MyClass(object):
... x = RevealAccess(10, 'var "x"')
... y = 5
...
>>> m = MyClass()
>>> m.x
Retrieving var "x"
10
>>> m.x = 20
Updating var "x"
>>> m.x
Retrieving var "x"
20
>>> m.y
5
總結(jié)
以上所述是小編給大家介紹的Python 中的 descriptor,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
python三元運(yùn)算符實(shí)現(xiàn)方法
這篇文章主要介紹了python實(shí)現(xiàn)三元運(yùn)算符的方法,大家參考使用吧2013-12-12
一文深入學(xué)習(xí)Python中的os.listdir函數(shù)
這篇文章主要給大家介紹了關(guān)于Python中os.listdir函數(shù)的相關(guān)資料,os.listdir是 Python中的一個(gè)函數(shù),它的意思是返回指定目錄下的文件和文件夾的名稱的列表,需要的朋友可以參考下2023-10-10
Python真題案例之小學(xué)算術(shù)?階乘精確值?孿生素?cái)?shù)?6174問題詳解
這篇文章主要介紹了python實(shí)操案例練習(xí),本文給大家分享的案例中主要任務(wù)有小學(xué)生算術(shù)、階乘的精確值、孿生素?cái)?shù)、6174問題,需要的小伙伴可以參考一下2022-03-03
NumPy實(shí)現(xiàn)從已有的數(shù)組創(chuàng)建數(shù)組
本文介紹了NumPy中如何從已有的數(shù)組創(chuàng)建數(shù)組,包括使用numpy.asarray,numpy.frombuffer和numpy.fromiter方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-10-10
Python自動(dòng)安裝第三方庫的小技巧(pip使用詳解)
很多朋友私信小編Python安裝第三方庫安裝技巧,在這就不一一回復(fù)大家了,今天小編給大家分享一篇教程關(guān)于Python自動(dòng)安裝第三方庫的小技巧,本文以安裝plotly為例給大家詳細(xì)講解,感興趣的朋友跟隨小編一起看看吧2021-05-05
Python3實(shí)現(xiàn)轉(zhuǎn)換Image圖片格式
本篇文章給大家分享了Python3實(shí)現(xiàn)在線轉(zhuǎn)換Image圖片格式的功能以及相關(guān)實(shí)例代碼,有興趣的朋友參考下。2018-06-06
django下創(chuàng)建多個(gè)app并設(shè)置urls方法
在本篇文章里小編給大家分享的是一篇關(guān)于django下創(chuàng)建多個(gè)app并設(shè)置urls方法,需要的朋友們可以參考學(xué)習(xí)下。2020-08-08

