欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中幾種屬性訪問的區(qū)別與用法詳解

 更新時(shí)間:2018年10月10日 08:37:48   作者:棲遲於一丘  
這篇文章主要給大家介紹了關(guān)于Python中幾種屬性訪問的區(qū)別和用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

起步

在Python中,對(duì)于一個(gè)對(duì)象的屬性訪問,我們一般采用的是點(diǎn)(.)屬性運(yùn)算符進(jìn)行操作。例如,有一個(gè)類實(shí)例對(duì)象foo,它有一個(gè)name屬性,那便可以使用foo.name對(duì)此屬性進(jìn)行訪問。一般而言,點(diǎn)(.)屬性運(yùn)算符比較直觀,也是我們經(jīng)常碰到的一種屬性訪問方式。

python的提供一系列和屬性訪問有關(guān)的特殊方法: __get__ , __getattr__ , __getattribute__ , __getitem__ 。本文闡述它們的區(qū)別和用法。

屬性的訪問機(jī)制

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

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

__getattr__ 方法

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

這個(gè)方法是當(dāng)對(duì)象的屬性不存在是調(diào)用。如果通過正常的機(jī)制能找到對(duì)象屬性的話,不會(huì)調(diào)用 __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__ 方法

這個(gè)方法會(huì)被無條件調(diào)用。不管屬性存不存在。如果類中還定義了 __getattr__ ,則不會(huì)調(diào)用 __getattr__() 方法,除非在 __getattribute__ 方法中顯示調(diào)用 __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)

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

__get__ 方法

這個(gè)方法比較簡(jiǎn)單說明,它與前面的關(guān)系不大。

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

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 # 不會(huì)調(diào)用 __get__
a.x  # 調(diào)用 __get__

如果查找的屬性是在描述符對(duì)象中,則這個(gè)描述符會(huì)覆蓋上文說的屬性訪問機(jī)制,體現(xiàn)在查找鏈的不同,而這個(gè)行文也會(huì)因?yàn)檎{(diào)用的不同而稍有不一樣:

  • 如果調(diào)用是對(duì)象實(shí)例(題目中的調(diào)用方式), a.x 則轉(zhuǎn)換為調(diào)用: 。 type(a).__dict__['x'].__get__(a, type(a))
  • 如果調(diào)用的是類屬性, A.x 則轉(zhuǎn)換為: A.__dict__['x'].__get__(None, A)
  • 其他情況見文末參考資料的文檔

__getitem__ 方法

這個(gè)調(diào)用也屬于無條件調(diào)用,這點(diǎn)與 __getattribute__ 一致。區(qū)別在于 __getitem__ 讓類實(shí)例允許 [] 運(yùn)算,可以這樣理解:

  • __getattribute__ 適用于所有 . 運(yùn)算符;
  • __getitem__ 適用于所有 [] 運(yùn)算符。
class A(object):
 a = 1

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

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

如果僅僅想要對(duì)象能夠通過 [] 獲取對(duì)象屬性可以簡(jiǎn)單的:

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

總結(jié)

當(dāng)這幾個(gè)方法同時(shí)出現(xiàn)可能就會(huì)擾亂你了。我在網(wǎng)上看到一份示例還不錯(cuò),稍微改了下:

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'])

可以結(jié)合輸出慢慢理解,這里還沒涉及繼承關(guān)系呢??傊?,每個(gè)以 __ get 為前綴的方法都是獲取對(duì)象內(nèi)部數(shù)據(jù)的鉤子,名稱不一樣,用途也存在較大的差異,只有在實(shí)踐中理解它們,才能真正掌握它們的用法。

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • 詳解Python中數(shù)據(jù)庫管理模塊shelve和dbm的應(yīng)用

    詳解Python中數(shù)據(jù)庫管理模塊shelve和dbm的應(yīng)用

    作為常用的 python 自帶數(shù)據(jù)庫管理模塊,shelve 和 dbm 都是非常方便的對(duì)象持久化存儲(chǔ)和檢索工具,本文將從用法、優(yōu)勢(shì)以及不同點(diǎn)等方面進(jìn)行介紹,希望對(duì)大家有所幫助
    2023-10-10
  • 人工智能學(xué)習(xí)Pytorch梯度下降優(yōu)化示例詳解

    人工智能學(xué)習(xí)Pytorch梯度下降優(yōu)化示例詳解

    這篇文章主要為大家介紹了人工智能學(xué)習(xí)Pytorch梯度下降優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11
  • 解決python3捕獲cx_oracle拋出的異常錯(cuò)誤問題

    解決python3捕獲cx_oracle拋出的異常錯(cuò)誤問題

    今天小編就為大家分享一篇解決python3捕獲cx_oracle拋出的異常錯(cuò)誤問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • Python文件時(shí)間操作步驟代碼詳解

    Python文件時(shí)間操作步驟代碼詳解

    這篇文章主要介紹了Python文件時(shí)間操作步驟代碼詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Python實(shí)現(xiàn)朗讀在線音頻和本地音頻

    Python實(shí)現(xiàn)朗讀在線音頻和本地音頻

    在日常的Python軟件開發(fā)中,我們經(jīng)常會(huì)遇到一個(gè)非常重要的功能需求——讓程序能夠讀取并顯示文本內(nèi)容,下面我們就來學(xué)習(xí)一下Python實(shí)現(xiàn)朗讀音頻的具體操作吧
    2024-03-03
  • OpenCV+python3實(shí)現(xiàn)視頻分解成圖片

    OpenCV+python3實(shí)現(xiàn)視頻分解成圖片

    這篇文章主要為大家詳細(xì)介紹了OpenCV+python3實(shí)現(xiàn)視頻分解成圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • LeetCode百錢買百雞python遞歸解法示例

    LeetCode百錢買百雞python遞歸解法示例

    這篇文章主要為大家介紹了LeetCode百錢買百雞題目python遞歸解法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Selenium+BeautifulSoup+json獲取Script標(biāo)簽內(nèi)的json數(shù)據(jù)

    Selenium+BeautifulSoup+json獲取Script標(biāo)簽內(nèi)的json數(shù)據(jù)

    這篇文章主要介紹了Selenium+BeautifulSoup+json獲取Script標(biāo)簽內(nèi)的json數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • pytorch 中pad函數(shù)toch.nn.functional.pad()的用法

    pytorch 中pad函數(shù)toch.nn.functional.pad()的用法

    今天小編就為大家分享一篇pytorch 中pad函數(shù)toch.nn.functional.pad()的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • 跟老齊學(xué)Python之通過Python連接數(shù)據(jù)庫

    跟老齊學(xué)Python之通過Python連接數(shù)據(jù)庫

    現(xiàn)在在做python的時(shí)候需要用到數(shù)據(jù)庫,于是自己重新整理了一下數(shù)據(jù)庫的知識(shí),并且熟悉了python中MysqlDB模塊的功能和函數(shù)等接口,現(xiàn)在系統(tǒng)地來總結(jié)一下吧
    2014-10-10

最新評(píng)論