亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一文解密Python中_getattr_和_getattribute_的用法與區(qū)別

 更新時間:2023年01月13日 14:52:28   作者:古明地覺  
這篇文章主要為大家詳細介紹了Python中_getattr_和_getattribute_的用法與區(qū)別,文中通過一些簡單的示例為大家進行了講解,需要的可以參考一下

__getattr__

當訪問實例對象的某個不存在的屬性時,毫無疑問會報錯,會拋出 AttributeError。

class?A:
????pass

a?=?A()
a.xxx
"""
AttributeError:?'A'?object?has?no?attribute?'xxx'
"""

但如果我們希望在找不到某個屬性時,不要報錯,而是返回默認值,該怎么做呢?這個時候我們就需要定義 __getattr__ 方法了,當實例對象找不到某個屬性時會執(zhí)行此方法。

class?Girl:

????def?__init__(self):
????????self.name?=?"古明地覺"
????????self.age?=?17

????def?get_info(self):
????????return?f"name:?{self.name},?age:?{self.age}"

????def?__getattr__(self,?item):
????????return?f"你訪問了?{item}?屬性"


girl?=?Girl()
print(girl.name,?girl.age)??#?古明地覺?17
print(girl.get_info)??#?<bound?method?Girl.get_info...>
print(girl.get_info())??#?name:?古明地覺,?age:?17

print(girl.xxx)??#?你訪問了?xxx?屬性
print(girl.yyy)??#?你訪問了?yyy?屬性
print(girl.zzz)??#?你訪問了?zzz?屬性

所以非常簡單,就是當實例對象訪問了一個不存在的屬性時,會執(zhí)行 __getattr__ 方法。當然,如果屬性存在的話,就不會執(zhí)行了,而是返回相應的值。

此外 __getattr__ 還有一個用法,就是在模塊導入的時候。假設我們有一個 tools.py,里面代碼如下:

def?__getattr__(name):
????return?f"{__name__}?中不存在?{name}"

name?=?"古明地覺"
age?=?17

相信你明白它是干什么的了,我們來導入它:

from?tools?import?name,?age,?xxx,?yyy

print(name,?age)??#?古明地覺?17
print(xxx)??#?tools?中不存在?xxx
print(yyy)??#?tools?中不存在?yyy

import?tools
print(tools.zzz)??#?tools?中不存在?zzz

在獲取 tools.py 里面的屬性時,如果不存在,那么同樣會去執(zhí)行 __getattr__,應該還是很簡單的。

__getattribute__

__getattribute__ 被稱為屬性攔截器,它比 __getattr__ 要霸道的多,這兩者的區(qū)別如下:

  • __getattr__:當訪問的屬性不存在時,才會執(zhí)行此方法;
  • __getattribute__:不管訪問的屬性是否存在,一律執(zhí)行此方法;

我們舉個例子:

class?Girl:

????def?__init__(self):
????????self.name?=?"古明地覺"
????????self.age?=?17

????def?__getattribute__(self,?item):
????????return?f"獲取屬性:?{item}"


girl?=?Girl()
print(girl.name)??#?獲取屬性:?name
print(girl.age)??#?獲取屬性:?age
print(girl.xxx)??#?獲取屬性:?xxx

#?即便你想通過屬性字典獲取也是沒有用的
#?因為不管什么屬性,都會執(zhí)行?__getattribute__
print(girl.__dict__)??#?獲取屬性:?__dict__

并且在使用這個方法的時候,一定要謹慎,因為你一不小心就會陷入無限遞歸。

class?Girl:

????def?__init__(self):
????????self.name?=?"古明地覺"
????????self.age?=?17

????def?__getattribute__(self,?item):
????????return?getattr(self,?item)


girl?=?Girl()
print(girl.name)
#?顯然上面的代碼會陷入無限遞歸
#?因為?girl.name?會調用?__getattribute__
#?而在里面又執(zhí)行了?getattr(self,?item),還是在獲取屬性
#?所以又會調用?__getattribute__,于是會無限遞歸

#?可能有人說,那我換一種方式
#?我將?getattr(self,?item)?改成?self.__dict__[item]?可以嗎
#?答案也是不行的,因為?self.__dict__?仍是在獲取屬性
#?只要獲取屬性,就會觸發(fā)?__getattribute__,依舊會陷入無限遞歸

所以 __getattribute__ 非常霸道,那么我們如何使用它呢?答案是通過父類。

class?Girl:

????def?__init__(self):
????????self.name?=?"古明地覺"
????????self.age?=?17

????def?__getattribute__(self,?item):
????????return?super().__getattribute__(item)


girl?=?Girl()
print(girl.name)
print(girl.age)
try:
????girl.xxx
except?AttributeError:
????print("屬性?xxx?不存在")
"""
古明地覺
17
屬性?xxx?不存在
"""

當我們調用父類的 __getattribute__ 時,如果屬性存在,它會直接返回;如果實例沒有該屬性,那么會檢測我們是否定義了 __getattr__,定義了則執(zhí)行,沒定義則拋出 AttributeError。我們將這兩個方法結合起來,看一個例子:

class?Girl:

????def?__init__(self):
????????self.name?=?"古明地覺"
????????self.age?=?17

????def?__getattr__(self,?item):
????????print(f"__getattr__?{item}")
????????return?f"獲取屬性?{item}"

????def?__getattribute__(self,?item):
????????print(f"__getattribute__?{item}")
????????return?super().__getattribute__(item)


girl?=?Girl()
#?不管屬性是否存在,一律調用?__getattribute__
#?然后在里面我們又調用了父類的?__getattribute__
#?那么會檢測屬性是否存在,存在則直接獲取對應的值,然后返回
print(girl.name)
"""
__getattribute__?name
古明地覺
"""
#?age?也是相同的邏輯,和?name?一樣,這兩個屬性都是存在的
print(girl.age)
"""
__getattribute__?age
17
"""

#?依舊執(zhí)行?__getattribute__,然后調用父類的?__getattribute__
#?由于屬性?xxx?不存在,于是會執(zhí)行?__getattr__
print(girl.xxx)
"""
__getattribute__?xxx
__getattr__?xxx
獲取屬性?xxx
"""

那么問題來了,這個 __getattribute__ 有啥用呢?該方法被稱為屬性攔截器,顯然它可以起到一個控制屬性訪問權限的作用。

class?Girl:

????def?__init__(self):
????????self.name?=?"古明地覺"
????????self.age?=?17

????def?__getattr__(self,?item):
????????return?f"屬性?{item}?不存在"

????def?__getattribute__(self,?item):
????????if?item?==?"age":
????????????return?"女人芳齡不可泄露,別問,問就是還不到?18?歲"
????????return?super().__getattribute__(item)


girl?=?Girl()
#?name?屬性存在,所以在?__getattribute__?中直接返回
print(girl.name)
"""
古明地覺
"""
#?age?也是如此,也是在?__getattribute__?中直接返回
#?只不過它相當于被攔截了
print(girl.age)
"""
女人芳齡不可泄露,別問,問就是還不到?18?歲
"""
#?父類在執(zhí)行?__getattribute__?的時候,發(fā)現(xiàn)?xxx?屬性不存在
#?于是會觸發(fā)?__getattr__?的執(zhí)行(如果沒定義則拋出?AttributeError)
print(girl.xxx)
"""
屬性?xxx?不存在
"""

所以 __getattribute__ 就相當于一個屬性攔截器,不管獲取啥屬性,都要先經過它。如果你發(fā)現(xiàn)有一些屬性不想讓外界訪問,那么直接攔截掉即可,比如上面代碼中的 age 屬性。

然后對于那些可以讓外界訪問的屬性,則需要調用父類的 __getattribute__ 幫我們去獲取(因為我們手動獲取的話會陷入無線遞歸),并且在獲取不存在的屬性時也會自動執(zhí)行 __getattr__。

當然啦,除了屬性,方法也是一樣的。

class?Girl:

????def?__init__(self):
????????self.name?=?"古明地覺"
????????self.age?=?17

????def?get_info(self):
????????return?f"name:?{self.name},?age:?{self.age}"

????def?__getattribute__(self,?item):
????????if?item?==?"get_info":
????????????return?"此方法禁止獲取"
????????return?super().__getattribute__(item)


girl?=?Girl()
print(girl.get_info)
"""
此方法禁止獲取
"""
#?默認情況下?girl.get_info?拿到的是一個方法
#?然后再加上小括號就會執(zhí)行該方法
#?但在?__getattribute__?中我們將其攔截了,并返回一個字符串
#?所以此時?girl.get_info()?就會報錯,因為字符串無法被調用

以上內容就是 __getattr__ 和 __getattribute__ 的區(qū)別與用法,在工作中看看能不能讓它們派上用場。不過說實話,__getattr__ 用的還是蠻頻繁的,而 __getattribute__ 則用的不多,至少我就很少用。

到此這篇關于一文解密Python中_getattr_和_getattribute_的用法與區(qū)別的文章就介紹到這了,更多相關Python getattr getattribute內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 解決在keras中使用model.save()函數保存模型失敗的問題

    解決在keras中使用model.save()函數保存模型失敗的問題

    這篇文章主要介紹了解決在keras中使用model.save()函數保存模型失敗的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • python讀取視頻流提取視頻幀的兩種方法

    python讀取視頻流提取視頻幀的兩種方法

    這篇文章主要為大家詳細介紹了python讀取視頻流提取視頻幀的兩種方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Python機器學習NLP自然語言處理基本操作新聞分類

    Python機器學習NLP自然語言處理基本操作新聞分類

    本文是Python機器學習NLP自然語言處理系列文章,開始我們自然語言處理 (NLP) 的學習旅程. 本文主要學習NLP自然語言處理基本操作新聞分類
    2021-09-09
  • Pytorch 實現(xiàn)權重初始化

    Pytorch 實現(xiàn)權重初始化

    今天小編就為大家分享一篇Pytorch 實現(xiàn)權重初始化,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • keras之權重初始化方式

    keras之權重初始化方式

    這篇文章主要介紹了keras之權重初始化方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • Python實現(xiàn)文件按照日期命名的方法

    Python實現(xiàn)文件按照日期命名的方法

    這篇文章主要介紹了Python實現(xiàn)文件按照日期命名的方法,涉及Python針對文件的遍歷、讀寫及時間操作相關技巧,需要的朋友可以參考下
    2015-07-07
  • 基于Pytorch的神經網絡之Regression的實現(xiàn)

    基于Pytorch的神經網絡之Regression的實現(xiàn)

    本文主要介紹了基于Pytorch的神經網絡之Regression的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • python 利用panda 實現(xiàn)列聯(lián)表(交叉表)

    python 利用panda 實現(xiàn)列聯(lián)表(交叉表)

    這篇文章主要介紹了python 利用panda 實現(xiàn)列聯(lián)表(交叉表),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Python繪制驚艷的?;鶊D的示例詳解

    Python繪制驚艷的?;鶊D的示例詳解

    很多時候,我們需要一種必須可視化數據如何在實體之間流動的情況。這個時候就需要?;鶊D,它通常描繪 從一個實體(或節(jié)點)到另一個實體(或節(jié)點)的數據流。本文將利用Python繪制驚艷的?;鶊D,需要的可以參考一下
    2022-02-02
  • python中使用numpy包的向量矩陣相乘np.dot和np.matmul實現(xiàn)

    python中使用numpy包的向量矩陣相乘np.dot和np.matmul實現(xiàn)

    本文主要介紹了python中使用numpy包的向量矩陣相乘np.dot和np.matmul實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02

最新評論