摘要:類實例方法,本身也是這與實例方法一致只不過,一個是綁定類類實例,另一個是綁定實例。
自定義函數的特殊屬性已經專門整理過一篇(Python 自定義函數的特殊屬性),方法的特殊屬性與其稍有不同,我們通過下面這個例子展開介紹:
class A(): def foo(self): """a method""" print("hellow world!") bar = foo @classmethod def clsmtd(cls, arg): print(str(arg)) a = A()實例方法的只讀屬性
與自定義函數的特殊屬性相比,實例方法具有 __self__,__func__ 這兩個函數所不具有的只讀屬性;此外,方法的 __doc__,__name__,__module__ 也是只讀。對于實例方法而言,其 __self__ 屬性為實例本身:
print(a.foo.__self__) # <__main__.A object at 0x00000233DF6DE2E8> print(a) # <__main__.A object at 0x00000233DF6DE2E8>
而 __func__ 屬性則返回方法所對應的底層函數:
print(a.foo) #> print(a.foo.__func__) #注意與 a.foo 的區別 #
至于 __doc__,__name__,__module__ 屬性則與函數相應屬性的值一致,所不同的是方法的這些屬性均為只讀,不可改寫:
print(a.foo.__doc__) # a method print(a.foo.__name__) # foo print(a.foo.__module__) # __main__實例方法可通過底層函數訪問函數屬性
不過,實例方法也可以通過其底層的 function 對象(通過 __func__ 屬性獲得)訪問函數所具有的特殊屬性,如:
print(a.foo.__func__.__code__)
# ", line 3>
因此,諸如 __doc__,__name__,__module__等屬性的值就可以通過底層函數相應的特殊屬性進行改寫:
a.foo.__doc__ = "raise error" # AttributeError: attribute "__doc__" of "method" objects is not writable print(a.foo.__func__.__doc__) # a method a.foo.__func__.__doc__ = "can be changed through func doc" print(a.foo.__doc__) # can be changed through func doc a.foo.__name__ = "dobi" # AttributeError: "method" object has no attribute "__name__" print(a.foo.__func__.__name__) # foo a.foo.__func__.__name__ = "dobi" print(a.foo.__name__) # dobi底層函數的唯一性
需要注意的是:當一個類的實例方法是通過其他實例方法創建,則其他實例方法所對應的底層函數并非其所創建的實例方法,而是其所創建的實例方法所對應的底層函數:
print(a.bar) #注意這里 a.bar 是個實例方法> print(a.bar.__func__) #
上例中,通過其他實例方法 a.bar 創建了實例方法 a.foo,但a.bar.__func__ 卻是 a.foo.__func__ 而非 a.foo:
print(a.foo.__func__) #實例方法的首位參數為實例本身print(a.foo) # >
實例方法執行時,其底層函數的首位參數為實例本身,下面兩行代碼執行結果是一致的:
a.foo() # hellow world! a.foo.__func__(a) # hellow world!類實例方法的首位參數是類本身
當一個實例方法(嚴格來說是類實例方法)是由類方法創建,則其 __self__ 屬性是其類本身:
print(a.clsmtd.__self__) #
事實上,通過類方法建立的(類)實例方法,在調用底層函數時(下例是 A.clsmtd.__func__),其首位參數(也即 __self__)是類本身,這一點與實例方法執行時有所區別。
a.clsmtd("dog") # dog A.clsmtd("dog") # dog A.clsmtd.__func__(A, "dog") # dog
類實例方法,本身也是 bound method,這與實例方法一致:
print(a.clsmtd) #> print(a.foo) # > print(A.clsmtd) # > print(A.foo) #
只不過,一個是綁定類(類實例),另一個是綁定實例。
總結Python 3 有兩種 bound method, 一種是 instance method,一種是 class method(class instance method),兩種都可以被實例訪問;
對于 instance method 其 __self__ 屬性值為 instance 本身,而 class method 其屬性值則為 class 本身;
不管是 instance method 還是 class method ,執行時,都需要調用與之對應的底層函數(underlying function,通過 __func__ 訪問),底層函數的首位參數通過 __self__ 獲得, 對于 instance method 其為該實例本身,對于 class method 則為該類本身;
bound method 可以通過對應的底層函數,訪問函數的所有特殊屬性。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38004.html
摘要:本篇繼續學習之路,實現更多的特殊方法以讓自定義類的行為跟真正的對象一樣。之所以要讓向量不可變,是因為我們在計算向量的哈希值時需要用到和的哈希值,如果這兩個值可變,那向量的哈希值就能隨時變化,這將不是一個可散列的對象。 《流暢的Python》筆記。本篇是面向對象慣用方法的第二篇。前一篇講的是內置對象的結構和行為,本篇則是自定義對象。本篇繼續Python學習之路20,實現更多的特殊方法以讓...
摘要:退出運行時上下文并返回一個布爾值旗標來表明所發生的任何異常是否應當被屏蔽。除了實現上下文管理協議以外,不同類型不會被特殊處理。其中一些并不會被內置函數所列出。 上一篇文章:Python標準庫---15、內置類型:集合類型、映射類型下一篇文章:Python標準庫---17、內置異常 上下文管理器類型 Python 的 with 語句支持通過上下文管理器所定義的運行時上下文這一概念。 此...
摘要:一利用動態屬性處理數據源屬性在中,數據的屬性和處理數據的方法統稱屬性。處理無效屬性名在中,由于關鍵字被保留,名稱為關鍵字的屬性是無效的。內置函數列出對象的大多數屬性。點號和內置函數會觸發這個方法。 導語:本文章記錄了本人在學習Python基礎之元編程篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、了解如何利用動態屬性處理數據;2、掌握Pyth...
摘要:以這種方式實現對象系統的目的是展示使用對象隱喻并不需要特殊的編程語言。我們的實現并不遵循類型系統的明確規定。反之,它為實現對象隱喻的核心功能而設計。是分發字典,它響應消息和。 2.6 實現類和對象 來源:2.6 Implementing Classes and Objects 譯者:飛龍 協議:CC BY-NC-SA 4.0 在使用面向對象編程范式時,我們使用對象隱喻來指導程序...
摘要:類對象被創建時存在于類命名空間內的所有名稱都是有效的屬性名稱。類的實例化,是使用函數表示法,可以把類對象看做是會返回一個新的類實例的函數。這就是可變對象作為類變量時的特性。類變量是所有類的實例共享的屬性和方法,實例變量是每個實例獨有的數據。 Python是面向對象的高級編程語言,在Python里面一切都是對象:數字、字符串、元組、列表、字典、集合等內置數據類型,以及函數、方法、類、模塊...
閱讀 1459·2021-09-30 09:57
閱讀 1466·2021-09-09 09:33
閱讀 2220·2021-09-04 16:40
閱讀 1792·2021-09-01 10:50
閱讀 3237·2021-09-01 10:31
閱讀 2539·2019-08-30 15:56
閱讀 2970·2019-08-30 15:44
閱讀 3475·2019-08-29 17:29