Python的魔法函式系列 __getattrbute__和__getattr__

昀溪發表於2018-12-16
 
#!/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

相關文章