python語法基礎學習筆記Task11:魔法方法

1、python的魔法方法

魔法方法是指Python內部已經包含的,被雙下劃線所包圍的方法,這些方法在進行特定的操作時會自動被調用,它們是Python面向對象下智慧的結晶

2、關於屬性的魔法方法

  • __ getattribute __(self, name)----定義了屬性被訪問時的行爲,而__getattr__只有該屬性不存在時纔會起作用,因此,在支持__getattribute__的Python版本,調用__getattr__前必定會調用 __ getattribute __,調用時應注意避免"無限遞歸"的錯誤。
  • __ getattr __(self, name)----該方法定義了你試圖訪問一個不存在的屬性時的行爲。因此,重載該方法可以實現捕獲錯誤拼寫然後進行重定向, 或者對一些廢棄的屬性進行警告。
  • __ setattr __(self, name, value)----是實現封裝的解決方案,它定義了你對屬性進行賦值和修改操作時的行爲。不管對象的某個屬性是否存在,它都允許你爲該屬性進行賦值,因此你可以爲屬性的值進行自定義操作,但是要注意避免"無限遞歸"的錯誤。
  • __ delattr __(self, name)----定義的是刪除屬性時的行爲,調用時注意避免"無限遞歸"的錯誤。
classAccess(object):

    def__getattr__(self, name):
        print '__getattr__'
        return super(Access, self).__getattr__(name)

    def__setattr__(self, name, value):
        print '__setattr__'
        return super(Access, self).__setattr__(name, value)

    def__delattr__(self, name):
        print '__delattr__'
        return super(Access, self).__delattr__(name)

    def__getattribute__(self, name):
        print '__getattribute__'
        return super(Access, self).__getattribute__(name)

access = Access()
access.attr1 = True  # __setattr__調用
access.attr1  # 屬性存在,只有__getattribute__調用
try:
    access.attr2  # 屬性不存在, 先調用__getattribute__, 後調用__getattr__
except AttributeError:
    pass
del access.attr1  # __delattr__調用
  • 無限遞歸錯誤
# 以上例子都是,每一次屬性賦值時, 方法都會被調用,因此不斷調用自身導致無限遞歸了
def __setattr__(self, name, value):
    self.name = value

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

def __getattribute__(self, name):
    return self.__dict__[name]

# 正確的寫法
def __setattr__(self, name, value):
    self.__dict__[name] = value
    
def __getattribute__(self, item):
    print('__getattribute__')
    return super().__getattribute__(self, item)

3、實例對象屬性尋找的順序

  • 首先訪問 __ getattribute __() 魔法方法(隱含默認調用,無論何種情況,均會調用此方法)。
  • 接着,去t.__dict__中查找是否具備該屬性。
  • 若在 t.__ dict __ 中找不到對應的屬性, 則去t.__ class __.__dict__中尋找。
  • 若在實例的類中也找不到該屬性,則去父類中尋找,即 t.__ class . bases __.__dict__中尋找。
  • 若以上均無法找到,則會調用 __ getattr __ 方法,執行內部的命令(若未重載 __ getattr __ 方法,則直接報錯:AttributeError)
class Test:
    def __getattr__(self, item):
        print('__getattr__')

    def __getattribute__(self, item):
        print('__getattribute__')
        #super().__getattribute__(item)
        #object.__getattribute__(self,item)

    def __setattr__(self, item, value):
        print('__setattr__')

    def __delattr__(self, item):
        print('__delattr__')

t = Test()
t.x
#__getarrtribute__

以上這個程序在訪問一個不存在的屬性的時候並沒有調用__ getattr __ ,而只是調用了__ getatrrribute __ 。這個的問題就出在了步驟的第④步,因爲,一旦重載了 __ getattribute __ () 方法,如果找不到屬性,則必須要手動加入第④步,否則是無法進入到 第⑤步 (__ getattr __)的。

  • 方法一:採用 object(所有類的基類)
class Test:#父類
    def __getattr__(self, item):
        print('__getattr__')

    def __getattribute__(self, item):
        print('__getattribute__')
        #super().__getattribute__(item)
        object.__getattribute__(self,item)

    def __setattr__(self, item, value):
        print('__setattr__')

    def __delattr__(self, item):
        print('__delattr__')

t = Test()
t.x
#__getattribute__
#__getattr__
  • 方法二:採用 super() 方法
class Test:#父類
    def __getattr__(self, item):
        print('__getattr__')

    def __getattribute__(self, item):
        print('__getattribute__')
        super().__getattribute__(item)
        #object.__getattribute__(self,item)

    def __setattr__(self, item, value):
        print('__setattr__')

    def __delattr__(self, item):
        print('__delattr__')

t = Test()
t.x
#__getattribute__
#__getattr__

4、一些基礎魔法方法
在這裏插入圖片描述
5、屬性相關的方法
在這裏插入圖片描述
6、比較操作符
在這裏插入圖片描述
7、算數運算符
在這裏插入圖片描述
參考文獻

  • https://blog.csdn.net/LSGO_MYP/article/details/102573292
  • https://blog.csdn.net/qq_38520096/article/details/79237593
  • https://www.cnblogs.com/zhouyixian/p/11129347.html
  • https://www.cnblogs.com/blackmatrix/p/5681480.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章