中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中的屬性訪問方式有哪些

發布時間:2021-01-28 15:10:25 來源:億速云 閱讀:200 作者:Leah 欄目:開發技術

本篇文章為大家展示了Python中的屬性訪問方式有哪些,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

屬性的訪問機制

一般情況下,屬性訪問的默認行為是從對象的字典中獲取,并當獲取不到時會沿著一定的查找鏈進行查找。例如 a.x 的查找鏈就是,從 a.__dict__['x'] ,然后是 type(a).__dict__['x'] ,再通過 type(a) 的基類開始查找。

若查找鏈都獲取不到屬性,則拋出 AttributeError 異常。

__getattr__ 方法

__getattr__函數的作用: 如果屬性查找(attribute lookup)在實例以及對應的類中(通過__dict__)失敗, 那么會調用到類的__getattr__函數, 如果沒有定義這個函數,那么拋出AttributeError異常。由此可見,__getattr__一定是作用于屬性查找的最后一步,兜底。

這個方法是當對象的屬性不存在是調用。如果通過正常的機制能找到對象屬性的話,不會調用 __getattr__ 方法。

class A:
 a = 1
 def __getattr__(self, item):
 print('__getattr__ call')
 return item

t = A()
print(t.a)
print(t.b)
# output
1
__getattr__ call
b

__getattribute__ 方法

這個方法會被無條件調用。不管屬性存不存在。如果類中還定義了 __getattr__ ,則不會調用 __getattr__() 方法,除非在 __getattribute__ 方法中顯示調用 __getattr__() 或者拋出了 AttributeError 。

class A:
 a = 1
 def __getattribute__(self, item):
 print('__getattribute__ call')
 raise AttributeError

 def __getattr__(self, item):
 print('__getattr__ call')
 return item

t = A()
print(t.a)
print(t.b)

所以一般情況下,為了保留 __getattr__ 的作用, __getattribute__() 方法中一般返回父類的同名方法:

def __getattribute__(self, item):
 return object.__getattribute__(self, item)

使用基類的方法來獲取屬性能避免在方法中出現無限遞歸的情況。

__get__ 方法

這個方法比較簡單說明,它與前面的關系不大。

如果一個類中定義了 __get__() , __set__() 或 __delete__() 中的任何方法。則這個類的對象稱為描述符。

class Descri(object):
 def __get__(self, obj, type=None):
 print("call get")

 def __set__(self, obj, value):
 print("call set")

class A(object):
 x = Descri()

a = A()
a.__dict__['x'] = 1 # 不會調用 __get__
a.x  # 調用 __get__

如果查找的屬性是在描述符對象中,則這個描述符會覆蓋上文說的屬性訪問機制,體現在查找鏈的不同,而這個行文也會因為調用的不同而稍有不一樣:

  • 如果調用是對象實例(題目中的調用方式), a.x 則轉換為調用: 。 type(a).__dict__['x'].__get__(a, type(a))

  • 如果調用的是類屬性, A.x 則轉換為: A.__dict__['x'].__get__(None, A)

  • 其他情況見文末參考資料的文檔

__getitem__ 方法

這個調用也屬于無條件調用,這點與 __getattribute__ 一致。區別在于 __getitem__ 讓類實例允許 [] 運算,可以這樣理解:

  • __getattribute__ 適用于所有 . 運算符;

  • __getitem__ 適用于所有 [] 運算符。

class A(object):
 a = 1

 def __getitem__(self, item):
 print('__getitem__ call')
 return item

t = A()
print(t['a'])
print(t['b'])

如果僅僅想要對象能夠通過 [] 獲取對象屬性可以簡單的:

def __getitem(self, item):
 return object.__getattribute__(self, item)

總結

當這幾個方法同時出現可能就會擾亂你了。我在網上看到一份示例還不錯,稍微改了下:

class C(object):
 a = 'abc'

 def __getattribute__(self, *args, **kwargs):
 print("__getattribute__() is called")
 return object.__getattribute__(self, *args, **kwargs)

 # return "haha"
 def __getattr__(self, name):
 print("__getattr__() is called ")
 return name + " from getattr"

 def __get__(self, instance, owner):
 print("__get__() is called", instance, owner)
 return self

 def __getitem__(self, item):
 print('__getitem__ call')
 return object.__getattribute__(self, item)

 def foo(self, x):
 print(x)

class C2(object):
 d = C()

if __name__ == '__main__':
 c = C()
 c2 = C2()
 print(c.a)
 print(c.zzzzzzzz)
 c2.d
 print(c2.d.a)
 print(c['a'])

上述內容就是Python中的屬性訪問方式有哪些,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

融水| 渭源县| 鲁甸县| 武威市| 上蔡县| 白水县| 墨玉县| 广西| 德惠市| 合水县| 滕州市| 丽水市| 武川县| 县级市| 西丰县| 那曲县| 东乡| 东明县| 马关县| 象山县| 崇州市| 图木舒克市| 房产| 南京市| 绥江县| 石渠县| 手机| 太保市| 玛曲县| 合水县| 雅安市| 曲靖市| 冕宁县| 云霄县| 成都市| 托克逊县| 延安市| 天水市| 两当县| 广宗县| 平遥县|