中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

Python中的類與對象之描述符詳解
來源:易賢網 閱讀:1630 次 日期:2015-03-31 15:42:04
溫馨提示:易賢網小編為您整理了“Python中的類與對象之描述符詳解”,方便廣大網友查閱!

這篇文章主要介紹了Python中的描述符詳解,屬于Python學習過程中類與對象的基本知識,需要的朋友可以參考下

描述符(Descriptors)是Python語言中一個深奧但卻重要的一部分。它們廣泛應用于Python語言的內核,熟練掌握描述符將會為Python程序員的工具箱添加一個額外的技巧。為了給接下來對描述符的討論做一些鋪墊,我將描述一些程序員可能會在日常編程活動中遇到的場景,然后我將解釋描述符是什么,以及它們如何為這些場景提供優雅的解決方案。在這篇總結中,我會使用新樣式類來指代Python版本。

1、假設一個程序中,我們需要對一個對象屬性執行嚴格的類型檢查。然而,Python是一種動態語言,所以并不支持類型檢查,但是這并不妨礙我們實現自己版本,且較為初級的類型檢查。對象屬性類型檢查的傳統方法可能采用下面的方式:

def __init__(self, name, age):

if isinstance(str, name):

self.name = name

else:

raise TypeError("Must be a string")

if isinstance(int, age):

self.age = age

else:

raise TypeError("Must be an int")

上面是執行這種類型檢查的一種方法,但是參數數量增加時它將變得比較繁瑣。另外,在賦值之前,我們可以創建一個在__init__中調用的type_check(type, val)函數,但是當我們想在其他地方設置屬性值時,該如何簡單地實現這種檢查呢。我想到的一個快速解決方案是Java中的getters和setters,但是這并不符合Python風格,并且比較麻煩。

2、假設在一個程序中,我們想創建一些在運行時立刻初始化然后變成只讀的屬性。有人也能想到利用Python中的特殊方法來實現,但這種實現方法仍舊是笨拙和繁瑣的。

3、最后,設想一個程序中,我們希望以某種方式自定義對象屬性的訪問。例如需要記錄這種屬性的訪問。同樣的,還是可以想到一個解決方法,即使這種解決方案可能比較笨重并且不可復用。

上述問題因都與屬性引用相關而全部聯系在了一起。下面,我們將嘗試自定義屬性的訪問方法。

Python描述符

針對上面所列的問題,描述符提供了優雅、簡潔、健壯和可重用的解決方案。簡而言之,一個描述符就是一個對象,該對象代表了一個屬性的值。這就意味著如果一個賬戶對象有一個屬性“name”,那么描述符就是另一個能夠用來代表屬性“name”持有值的對象。描述符協議中“定義了__get__”、“__set__”或”__delete__” 這些特殊方法,描述符是實現其中一個或多個方法的對象。這些方法中每一種方法的簽名如下所示:

python descr.get(self,obj,type=None)->value。

descr.__set__(self, obj, value) --> None

descr.__delete__(self, obj) --> None

實現__get__方法的對象是非數據描述符,意味著在初始化之后它們只能被讀取。而同時實現__get__和__set__的對象是數據描述符,意味著這種屬性是可寫的。

為了更好地理解描述符,我們給出針對上述問題基于描述符的解決方法。使用Python描述符實現對象屬性的類型檢查將是一個非常簡單的任務。裝飾器實現這種類型檢查的代碼如下所示:

class TypedProperty(object):

def __init__(self, name, type, default=None):

self.name = "_" + name

self.type = type

self.default = default if default else type()

def __get__(self, instance, cls):

return getattr(instance, self.name, self.default)

def __set__(self,instance,value):

if not isinstance(value,self.type):

raise TypeError("Must be a %s" % self.type)

setattr(instance,self.name,value)

def __delete__(self,instance):

raise AttributeError("Can't delete attribute")

class Foo(object):

name = TypedProperty("name",str)

num = TypedProperty("num",int,42)

>> acct = Foo()

>> acct.name = "obi"

>> acct.num = 1234

>> print acct.num

1234

>> print acct.name

obi

# trying to assign a string to number fails

>> acct.num = '1234'

TypeError: Must be a <type 'int'>

在這個例子中,我們實現了一個描述符TypedProperty,并且這個描述符類會對它所代表的類的任何屬性執行類型檢查。注意到這一點很重要,即描述符只能在類級別進行合法定義,而不能在實例級別定義。例如,在上面例子中的__init__方法里。

當訪問類Foo實例的任何屬性時,描述符會調用它的__get__方法。需要注意的是,__get__方法的第一個參數是描述符代表的屬性被引用的源對象。當屬性被分配時,描述符會調用它的__set__方法。為了理解為什么可以使用描述符代表對象屬性,我們需要理解Python中屬性引用解析的執行方式。對于對象來說,屬性解析機制在object.__getattribute__()中。該方法將b.x轉換成type(b).__dict__['x'].__get__(b, type(b))。然后,解析機制使用優先級鏈搜索屬性,在優先級鏈中,類字典中發現的數據描述符的優先級高于實例變量,實例變量優先級高于非數據描述符,如果提供了getattr(),優先級鏈會為getattr()分配最低優先級。對于一個給定的對象類,可以通過自定義__getattribute__方法來重寫優先級鏈。

深刻理解優先級鏈之后,就很容易想出針對前面提出的第二個和第三個問題的優雅解決方案了。那就是,利用描述符實現一個只讀屬性將變成實現數據描述符這個簡單的情況了,即不帶__set__方法的描述符。盡管在本例中不重要,定義訪問方式的問題只需要在__get__和__set__方法中增加所需的功能即可。

類屬性

每次我們想使用描述符的時候都不得不定義描述符類,這樣看起來非常繁瑣。Python特性提供了一種簡潔的方式用來向屬性增加數據描述符。一個屬性簽名如下所示:

?

1

property(fget=None, fset=None, fdel=None, doc=None) -> property attribute

fget、fset和fdel分別是類的getter、setter和deleter方法。我們通過下面的一個示例來說明如何創建屬性:

class Accout(object):

def __init__(self):

self._acct_num = None

def get_acct_num(self):

return self._acct_num

def set_acct_num(self, value):

self._acct_num = value

def del_acct_num(self):

del self._acct_num

acct_num = property(get_acct_num, set_acct_num, del_acct_num, "Account number property.")

如果acct是Account的一個實例,acct.acct_num將會調用getter,acct.acct_num = value將調用setter,del acct_num.acct_num將調用deleter。

在Python中,屬性對象和功能可以像《描述符指南》中說明的那樣使用描述符協議來實現,如下所示:

class Property(object):

"Emulate PyProperty_Type() in Objects/descrobject.c"

def __init__(self, fget=None, fset=None, fdel=None, doc=None):

self.fget = fget

self.fset = fset

self.fdel = fdel

if doc is None and fget is not None:

doc = fget.__doc__

self.__doc__ = doc

def __get__(self, obj, objtype=None):

if obj is None:

return self

if self.fget is None:

raise AttributeError("unreadable attribute")

return self.fget(obj)

def __set__(self, obj, value):

if self.fset is None:

raise AttributeError("can't set attribute")

self.fset(obj, value)

def __delete__(self, obj):

if self.fdel is None:

raise AttributeError("can't delete attribute")

self.fdel(obj)

def getter(self, fget):

return type(self)(fget, self.fset, self.fdel, self.__doc__)

def setter(self, fset):

return type(self)(self.fget, fset, self.fdel, self.__doc__)

def deleter(self, fdel):

return type(self)(self.fget, self.fset, fdel, self.__doc__)

Python也提供了@ property裝飾器,可以用它來創建只讀屬性。一個屬性對象擁有getter、setter和deleter裝飾器方法,可以使用它們通過對應的被裝飾函數的accessor函數創建屬性的拷貝。下面的例子最好地解釋了這一點:

class C(object):

def __init__(self):

self._x = None

@property

# the x property. the decorator creates a read-only property

def x(self):

return self._x

@x.setter

# the x property setter makes the property writeable

def x(self, value):

self._x = value

@x.deleter

def x(self):

del self._x

如果我們想讓屬性只讀,那么我們可以去掉setter方法。

在Python語言中,描述符有著廣泛的應用。Python函數、類方法、靜態方法都是非數據描述符的例子。針對列舉的Python對象是如何使用描述符實現的問題,《描述符指南》給出了一個基本的描述。

更多信息請查看IT技術專欄

更多信息請查看數據庫
易賢網手機網站地址:Python中的類與對象之描述符詳解
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
午夜精品在线| 久久久久高清| 激情一区二区三区| 亚洲国产精品一区二区三区| 西西人体一区二区| 国产精品区免费视频| 性欧美激情精品| 国产精品毛片一区二区三区| 一区二区三区日韩在线观看| 欧美日韩亚洲网| 欧美在线视频免费| 国外成人免费视频| 欧美一区二区免费视频| 精品69视频一区二区三区| 久久综合久久综合这里只有精品| 一区二区欧美日韩| 欧美jizz19性欧美| 国产精品毛片在线| 亚洲国产精品悠悠久久琪琪| 午夜精品免费| 国产精品久久久久久久久久免费看| 在线不卡亚洲| 久久亚洲春色中文字幕| 国产午夜精品理论片a级大结局| 欧美日本一区二区高清播放视频| 亚洲韩日在线| 国产精品久久久久久久久久尿| 在线一区亚洲| 国产精品一区一区| 久久久久久久久蜜桃| 亚洲视频免费| 国产亚洲一级| 欧美日韩国产精品一区二区亚洲| 久久精品国产亚洲aⅴ| 亚洲国产精品成人久久综合一区| 欧美精品v日韩精品v韩国精品v | 国产日韩欧美精品综合| 欧美一区二区三区免费在线看| 国产亚洲欧美日韩美女| 国产精品九九| 久久亚洲视频| 中文久久精品| 日韩午夜av| 91久久极品少妇xxxxⅹ软件| 国产精品欧美久久| 理论片一区二区在线| 亚洲美女视频| 亚洲国产精品va在线看黑人| 国产精品夜夜夜| 欧美国产乱视频| 欧美成人亚洲成人| 久久精品国产99国产精品| 亚洲精品三级| 尤物yw午夜国产精品视频明星| 国产一区二区三区在线观看精品 | 久久综合久久久久88| 亚洲性夜色噜噜噜7777| 国产综合久久久久久| 国产丝袜一区二区三区| 欧美日一区二区三区在线观看国产免 | 亚洲美女福利视频网站| 国产精品久久久久国产精品日日 | 国产精品日韩欧美大师| 欧美国产精品日韩| 中文在线不卡视频| 宅男噜噜噜66一区二区| 亚洲欧洲美洲综合色网| 黄色成人av在线| 欧美视频一区二区三区四区| 欧美精品福利视频| 欧美成人性生活| 麻豆av一区二区三区久久| 欧美二区在线| 欧美激情二区三区| 欧美黑人国产人伦爽爽爽| 欧美日韩国产三区| 欧美日韩午夜视频在线观看| 欧美激情一区二区三区| 国产精品久久久久aaaa樱花 | 欧美激情精品久久久久久变态| 久久久亚洲精品一区二区三区| 9久re热视频在线精品| 亚洲综合色激情五月| 亚洲无亚洲人成网站77777 | 欧美在线黄色| 性欧美长视频| 欧美伊人久久| 欧美日韩精品一二三区| 欧美性猛交99久久久久99按摩| 欧美日韩三级电影在线| 国产精品99久久久久久久久久久久| 亚洲私人黄色宅男| 午夜视黄欧洲亚洲| 欧美大色视频| 欧美午夜片在线观看| 国产九区一区在线| 亚洲卡通欧美制服中文| 亚洲视频1区| 欧美在线视频一区二区| 亚洲女人小视频在线观看| 美国成人直播| 欧美日韩日韩| 国产一区二区久久久| 国产一区二区高清| 亚洲国产精品久久久久秋霞蜜臀| 亚洲精品一区在线观看| 亚洲夜晚福利在线观看| 欧美国产精品劲爆| 国内精品久久久久影院色| 亚洲美女av在线播放| 亚洲女女女同性video| 亚洲精品免费观看| 久久久999国产| 亚洲精品男同| 国产精品日韩在线一区| 翔田千里一区二区| 国内外成人在线| 在线一区视频| 午夜精品电影| 欧美日韩视频在线一区二区观看视频| 亚洲一区二区三区成人在线视频精品| 激情欧美日韩一区| 99天天综合性| 久久午夜国产精品| 国产综合欧美| 欧美一区二区视频免费观看| 狠狠色狠狠色综合日日小说| 亚洲福利视频二区| 小黄鸭视频精品导航| 麻豆免费精品视频| 久久全国免费视频| 国产精品午夜av在线| 免费一区视频| 亚洲高清av在线| 国产精品自拍网站| 一区二区三区四区五区精品视频| 欧美成人午夜| 亚洲日本va午夜在线电影| 欧美日韩视频在线一区二区 | 日韩一级不卡| 免费亚洲一区二区| 亚洲国产日韩一级| 欧美激情精品久久久久久黑人 | 久久久久久综合| 国模大胆一区二区三区| 久久久青草青青国产亚洲免观| 黑丝一区二区三区| 欧美成人午夜剧场免费观看| 日韩午夜电影| 国产精品免费视频观看| 欧美一区二区三区久久精品 | 亚洲欧美www| 国产午夜精品理论片a级探花| 久久黄色级2电影| 在线观看91精品国产麻豆| 欧美成人中文字幕| 正在播放日韩| 国产亚洲综合精品| 欧美二区在线看| 亚洲一区三区电影在线观看| 国产亚洲成年网址在线观看| 免费观看亚洲视频大全| 一区二区三区久久精品| 国产日韩欧美一区二区| 蜜臀av一级做a爰片久久| 一本不卡影院| 红桃视频国产精品| 欧美激情性爽国产精品17p| 亚洲免费视频成人| 1204国产成人精品视频| 欧美日韩在线精品一区二区三区| 欧美一级在线视频| 亚洲人成在线观看一区二区| 国产精品伊人日日| 欧美成人日韩| 久久se精品一区二区| 亚洲美女在线看| 含羞草久久爱69一区| 欧美日韩一区二区在线观看视频 | 欧美精品日韩综合在线| 亚洲综合视频1区| 最新日韩精品| 国产一区二区日韩精品| 欧美日韩国产a| 美日韩精品视频| 欧美资源在线| 亚洲一区网站| 99精品欧美一区二区蜜桃免费| 黄网站免费久久| 国产精品一页| 国产精品国产三级国产a| 欧美成人综合| 久久字幕精品一区| 久久精品国产一区二区三区| 一区二区三区四区在线| 亚洲人成网站色ww在线| 亚洲大胆女人| 在线看片成人| 亚洲第一级黄色片| 一区二区在线免费观看|