#!/usr/bin/env python # -*- coding: utf-8 -*- import sys __metaclass__ = type """ __getattr__ 和 __getattribute__ 的區別 """ class ClassName: def __init__(self, name, info={}): self.name = name self.info = info # def __getattribute__(self, item): # """ # 這個魔法函式也是針對屬性的,但是它的特點是在__getattr__之前執行,而且無論你訪問 # 的屬性是不是存在都返回這個函式里面的返回值。也就是你訪問什麼屬性都返回一樣的東西。 # 所以這個方法儘量不要自己重寫。 # :param item: # :return: # """ # return "HELLO" def __getattr__(self, item): """ 這個魔法函式式在你試圖訪問一個不存在的屬性時呼叫的,如果沒有這個魔法函式 訪問不存在的屬性程式會報錯,但是如果有這個函式你就可以加入邏輯處理,比如 返回一個 None,或者列印一些提示內容,或者進行糾正,比如你的屬性都是小寫 對方訪問一個大寫的,你這裡就可以自動轉換等 :param item: :return: None 其實不加return預設也會返回None """ return self.info.get(item) # print("not found.", item) # return None if __name__ == "__main__": cn = ClassName("Tom", info={"sex": "F"}) # 本身類裡面沒有sex這個屬性,我們透過字典傳遞進去的,你可以使用 __getattr__ 魔法函式,其實它就是去 __dict__裡面去找 # 讓他可以訪問字典。 print(cn.sex) print(cn.__dict__)
如果我們把__getattribute__取消註釋再次執行
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys __metaclass__ = type """ __getattr__ 和 __getattribute__ 的區別 """ class ClassName: def __init__(self, name, info={}): self.name = name self.info = info def __getattribute__(self, item): """ 這個魔法函式也是針對屬性的,但是它的特點是在__getattr__之前執行,而且無論你訪問 的屬性是不是存在都返回這個函式里面的返回值。也就是你訪問什麼屬性都返回一樣的東西。 所以這個方法儘量不要自己重寫。 :param item: :return: """ return "HELLO" def __getattr__(self, item): """ 這個魔法函式式在你試圖訪問一個不存在的屬性時呼叫的,如果沒有這個魔法函式 訪問不存在的屬性程式會報錯,但是如果有這個函式你就可以加入邏輯處理,比如 返回一個 None,或者列印一些提示內容,或者進行糾正,比如你的屬性都是小寫 對方訪問一個大寫的,你這裡就可以自動轉換等 :param item: :return: None 其實不加return預設也會返回None """ return self.info.get(item) # print("not found.", item) # return None if __name__ == "__main__": cn = ClassName("Tom", info={"sex": "F"}) # 本身類裡面沒有sex這個屬性,我們透過字典傳遞進去的,你可以使用 __getattr__ 魔法函式,其實它就是去 __dict__裡面去找 # 讓他可以訪問字典。 print(cn.sex) print(cn.__dict__)
兩次結果都是HELLO