摘要:這里設置的是實例屬性實例屬性會覆蓋描述符的方法類的描述符依然存在刪除實例屬性再讀取時就會出發描述符的方法
描述符:描述符類的實例是托管類的類屬性
用于研究描述符行為的幾個方法:
def cls_name(obj_or_cls): cls = type(obj_or_cls) if cls is type: cls = obj_or_cls return cls.__name__.split(".")[-1] def display(obj): cls =type(obj) if cls is type: return "".format(obj.__name__) elif cls in [type(None), int]: return repr(obj) else: return "<{} object>".format(cls_name(obj)) def print_args(name, *args): persudo_args = ",".join(display(x) for x in args) print("-> {}.__{}__({}))".format(cls_name(args[0]), name, persudo_args)) class Overriding: """由get 和set 方法的數據描述符,也稱覆蓋型描述符""" def __get__(self, instance, owner): print_args("get", self, instance, owner) def __set__(self, instance, value): print_args("set", self, instance, value) class OverridingNoGet: """沒有get方法的數據描述符,也稱覆蓋型描述符""" def __set__(self, instance, value): print_args("set", self, instance, vvalue) class NonOverriding: """沒有set方法的非數據描述符,也稱非覆蓋型描述符""" def __get__(self, instance, owner): print_args("get", self, instance, owner) class Managed: over = Overriding() over_no_get = OverridingNoGet() non_over = NonOverriding() def spam(self): print("-> Managed.spam({})".format(display(self)))
覆蓋型描述符,也叫數據型描述符
>>> from demo import * >>> m = Manged() >>> m.over #get里的參數分別對應[self]Overriding實例, [instance]Managed實例,[owner]Managed類 -> Overriding.__get__(, , )) >>> Managed.over #類直接調用屬性,instance的位置為None。 -> Overriding.__get__( ,None, )) >>> m.over = 7 #[self]->Overriding的實例, [instance]->Managed類的實例,[value]->設置的值[7] -> Overriding.__set__( , ,7)) >>> m.over #讀取m.over, 還是出發__get__方法 -> Overriding.__get__( , , )) >>> m.__dict__["over"] = 8 #直接通過__dict__方法設置實例屬性 >>> vars(m) #__dict__屬性中已經有了over屬性 {"over": 8} >>> m.over #但是,實現了set方法的覆蓋型描述符會跳過實例屬性,直接讀取描述符屬性 -> Overriding.__get__( , , ))
沒有get方法的覆蓋型描述符
>>> m.over_no_get #沒有__get__方法,所以返回描述符實例>>> Managed.over_no_get #直接從托管類Managed中讀取描述符實例也是如此 >>> m.over_no_get = 7 #設置值時出發__set__方法 -> OverridingNoGet.__set__( , ,7)) >>> m.__dict__["over_no_get"] = 7 #通過實例的__dict__屬性設置名為over_no_get的實例屬性 >>> m.over_no_get #現在,實例屬性會覆蓋描述符,因為沒有定義__get__方法 7 >>> m.over_no_get = 7 #設置屬性值時還是會觸發描述符的__set__方法 -> OverridingNoGet.__set__( , ,7))
非覆蓋型描述符,也叫非數據描述符
>>> m.non_over #出發描述符的__get__方法 -> NonOverriding.__get__(, , )) >>> m.non_over = 7 #沒有__set__方法,所以沒有干涉賦值操作。這里設置的是實例屬性 >>> m.non_over #實例屬性會覆蓋描述符的__get__方法 7 >>> m.__dict__ {"non_over": 7} >>> Managed.non_over #類的描述符依然存在 -> NonOverriding.__get__( ,None, )) >>> del m.non_over #刪除實例屬性 >>> m.__dict__ {} >>> m.non_over #再讀取m.non_over時就會出發描述符的__get__方法 -> NonOverriding.__get__( , , ))
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43849.html
摘要:最近在閱讀微型框架的源碼,發現了中有一個既是裝飾器類又是描述符的有趣實現。所以第三版的代碼可以這樣寫第三版的代碼沒有使用裝飾器,而是使用了描述符這個技巧。更大的問題來自如何將描述符與裝飾器結合起來,因為是一個類而不是方法。 最近在閱讀Python微型Web框架Bottle的源碼,發現了Bottle中有一個既是裝飾器類又是描述符的有趣實現。剛好這兩個點是Python比較的難理解,又混合在...
摘要:下面我們用描述符來實現中的動態屬性和特性中提及的訂單結算代碼第四版使用描述符實現訂單結算功能描述符基于協議實現,無需創建子類。特性是覆蓋型描述符。非覆蓋型描述符沒有實現方法的描述符屬于非覆蓋型描述符。類中定義的方法是非覆蓋型描述符。 導語:本文章記錄了本人在學習Python基礎之元編程篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、了解描述符...
摘要:之所以是這樣是因為當訪問一個實例描述符對象時,會將轉換為。而類的字典中則有描述符對象。這主要就是因為描述符優先。此外,非數據描述符的優先級低于實例屬性。參考以上就是本人對描述符的一些理解,有什么不正確的地方還請不吝指出,謝謝 什么是描述符 python描述符是一個綁定行為的對象屬性,在描述符協議中,它可以通過方法重寫屬性的訪問。這些方法有 __get__(), __set__(), 和...
摘要:由上面的注釋,可以看出其實就相當于一個描述符類,而在此刻變成了一個描述符。調用這個方法可以知道,每調用一次,它都會經過描述符類的。基于描述符如何實現同樣的也是一樣。我想你應該對描述符在中的應用有了更深的理解。好吧,我承認我標題黨了。但是這篇文章的知識點,你有極大的可能并不知道。 前段時間,我寫了一篇描述符的入門級文章,從那些文章里你知道了如何定義描述符,且明白了描述符是如何工作的。 如果你還...
閱讀 1480·2021-11-17 09:33
閱讀 1260·2021-10-11 10:59
閱讀 2892·2021-09-30 09:48
閱讀 1904·2021-09-30 09:47
閱讀 3024·2019-08-30 15:55
閱讀 2336·2019-08-30 15:54
閱讀 1492·2019-08-29 15:25
閱讀 1645·2019-08-29 10:57