二. __getattribute__


二. __getattribute__

1. 先看看 : __getattr__

  • 點 . 屬性 沒找到觸發
class Bar:

    def __getattr__(self, item):
        print("沒找到,觸發了我")

bb = Bar()
bb.name    # 沒找到,觸發了我

2.__getattribute__

  • 點 . 屬性 無論找沒找到都觸發
class Bar:
    def __init__(self,name):
        self.name = name

    def __getattribute__(self, item):
        print(f"無論找沒找到,都觸發了我-->{item}")

bb = Bar("shawn")
bb.name  # 無論找沒找到,都觸發了我-->name
bb.age   # 無論找沒找到,都觸發了我-->age

3.兩者同時存在

🍔兩者同時存在
class Bar:
    def __init__(self,name):
        self.name = name

    def __getattr__(self, item):
        print("沒找到,觸發了我")

    def __getattribute__(self, item):
        print(f"無論找沒找到,都觸發了我-->{item}")

bb = Bar("shawn")
bb.name  # 無論找沒找到,都觸發了我-->name
bb.age   # 無論找沒找到,都觸發了我-->age

🍔設置異常
class Bar:
    def __init__(self,name):
        self.name = name

    def __getattr__(self, item):
        print("沒找到,觸發了我")

    def __getattribute__(self, item):
        print(f"無論找沒找到,都觸發了我-->{item}")
        raise AttributeError('讓小弟接管')  # 設置異常,直接交給__getattr__

bb = Bar("shawn")
bb.name
'''
無論找沒找到,都觸發了我-->name
沒找到,觸發了我
'''
bb.age
'''
無論找沒找到,都觸發了我-->age
沒找到,觸發了我
'''
  • [對象] . [屬性] 的調用順序 : 先執行 __getattribute__--->去類的名稱空間找--->__getattr__(本質是去對象自己的名稱空間找)
  • [對象] . [屬性] 的查找順序 : 對象自己--->--->父類--->父類

4.總結

  • __getattribute__方法優先級比__getattr__
  • 沒有重寫__getattribute__的情況下, 默認使用的是父類的__getattribute__方法
  • 只有在使用默認__getattribute__方法中找不到對應的屬性時,才會調用__getattr__
  • 如果是對不存在的屬性做處理,盡量把邏輯寫在__getattr__方法中
  • 如果非得重寫__getattribute__方法,需要注意兩點:
    • 第一是避免.操作帶來的死循環
    • 第二是不要遺忘父類的__getattribute__方法在子類中起的作用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM