python類特列方法使用

class Rgc(object):
    def __new__(cls, *args, **kwargs):
        print('在類通過__new__方法實例化一個對象')
        return super(Rgc, cls).__new__(cls)

    def __init__(self, name, gender):
        """
        Usage:
        >>> Rgc('rg','man')
        :param name:
        :param gender:
        """
        print('在類通過__new__方法實例化爲一個對象後,此方法是對這個對象 參數的初始化(先執行__new__,再執行__init)')
        self.name = name
        self.gender = gender

    def __call__(self, age):
        """
        把類實例化對象當做一個方法調用;

        Usage:
            >>> rg_obj=Rgc('rg','man')
            >>> rg_obj(14)
            >>> 14

            >>> Rgc('rg','man')(14)
            >>> 14

        :param age:
        :return:
        """
        print("""把類實例化對象當做一個方法調用;""")
        return age

    def __str__(self):
        return '用戶輸出的數據,通過print方法顯示的內容'

    def __repr__(self):
        return "控制檯輸出的內容,只有在控制檯時纔會顯示"

    def __enter__(self):
        """
        __enter__方法配合__exit__方法使用,主要用來 以 with xxxx as xxx: 的方式(比如訪問文件)調用
        __enter__ 必須有 return ,並且return 的結果作爲as後面的變量使用。

        Usage:
            >>> with Rgc('rg','girl') as rg_obj:
            >>>     print(rg_obj.name)

        :return: obj
        """
        print('進入with')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        __exit__函數 是 在 with xxxx as xxx: 的語句結束時需要處理的相關數據,如釋放鏈接,清除內存等
        :param exc_type:
        :param exc_val:
        :param exc_tb:
        :return:
        """

        print('退出with')


class St():
    mana_list = []
    mana_dict = {}

    def __init__(self, num):
        self.names = num
        self.mana_list.append(num)
        self.mana_dict[num] = self

    def __getitem__(self, item):
        """
        此方法可以把對象模擬成list或dict 的方式調用,即 key-val 類型
        但是此方法 需要用到 類屬性,類多次實例化時,類屬性的值共享,所以 需要注意 使用情況
        使用事例 如下方 代碼
        :param item:
        :return:
        """
        if isinstance(item, str):
            return self.mana_dict[item]
        else:
            return self.mana_list[item]


fir = St('first')
sec = St('secound')
thi = St('third')
print(thi.mana_list, '分割',
      thi.mana_dict)  # ['first', 'secound', 'third'],'分割', {'first': <__main__.St object at 0x000001C6DF19AA58>, 'secound': <__main__.St object at 0x000001C6DF19AA90>, 'third': <__main__.St object at 0x000001C6DF19AAC8>}

print(thi[1], thi['third'].names)  # secound third

print(fir.__dict__)  # {'names': 'first'}    總結:實例化對象的__dict__存了實例化屬性,即 self.xxx=yyy
print(St.__dict__)
# {'__module__': '__main__', 'mana_list': ['first', 'secound', 'third'], 'mana_dict': {'first': <__main__.St object at 0x00000231144BAA90>, 'secound': <__main__.St object at 0x00000231144BAAC8>, 'third': <__main__.St object at 0x00000231144BAB00>}, '__init__': <function St.__init__ at 0x00000231144CF1E0>, '__getitem__': <function St.__getitem__ at 0x00000231144CF268>, '__dict__': <attribute '__dict__' of 'St' objects>, '__weakref__': <attribute '__weakref__' of 'St' objects>, '__doc__': None}
# 總結:類的__dict__存了全局變量,靜態函數,類函數,普通函數,內置屬性

print(fir.__dir__())
# ['names', '__module__', 'mana_list', 'mana_dict', '__init__', '__getitem__', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
# 總結:實例化的 __dir__() 存了 全局變量,靜態函數,類函數,普通函數,內置屬性 的名字 列表

print(thi.__class__.mana_list)  # 獲取實例化 屬性值
print(thi.__class__.__name__)  # 獲取 實例化 類 的 名字 字符串 值

print('*' * 20)


class AttTest():
    nu = 1
    a = 4

    def __init__(self, nu):
        self.nu = nu

    def __getattr__(self, item):
        """
        屬性查找順序爲:
        實例的__getattribute__-->實例對象字典-->實例所在類字典-->實例所在類的父類(MRO順序)字典-->實例所在類的__getattr__-->報錯
        :param item:
        :return:
        """
        print('在訪問未定義的屬性時,調用此方法,如果不顯示的引用此方法 則程序直接報錯;此方法在屬性訪問順序的末端')
        return '不存在此屬性'


te = AttTest(20)
print(te.nu, AttTest.nu)
print(getattr(te, 'nu'), 'getattr 實例化')  # getattr() 方法訪問實例的屬性  結果爲 20
print(getattr(AttTest, 'nu'), 'getattr obj')  # getattr() 方法訪問類屬性 結果爲 1
print(te.a1)

print('*' * 20)


class AttTestOne:
    nu = 1
    a = 4

    def __init__(self, nu):
        self.nu = nu

    def __getattribute__(self, item):
        """
        此方法 叫 屬性訪問攔截器,此攔截器是 屬性訪問順序中 優先級最高的,會先執行此方法的代碼;
        屬性查找順序爲:
        實例的__getattribute__-->實例對象字典-->實例所在類字典-->實例所在類的父類(MRO順序)字典-->實例所在類的__getattr__-->報錯

        waring: 注意此方法 如果 return self.item 會造成 死循環
        :param item:
        :return:
        """
        print('start getattribute func')
        if item == 'nu':
            return True
        return False


te_one = AttTestOne(22)
print(te_one.nu)

print('*' * 20)


class SetattTest(object):
    private = ['age']

    def __init__(self, job):
        self.job = job

    def __setattr__(self, key, value):
        """
        此__setattr__ 在對實例 賦值,或者在__init__中初始化參數時,調用此方法,注意 此方法裏面 不要使用 self.key=value ,因爲會無限 調用 __setattr__方法 導致報錯。
        此方法 在設置屬性時使用 self.__dict__[key] = value
        其他功能 比如 可以強制設置類的private方法

        :param key:
        :param value:
        :return:
        """
        print('start {},{}'.format(key, value))
        # self.key=value
        if key in self.private:
            raise AttributeError('this attribute can not be changed!')
        else:
            self.__dict__[key] = value
            # self.key=value # 對屬性賦值不要用此方法,會無限循環最終報錯


aa = SetattTest('work')
aa.name = 'a'
# aa.age = 'b'
print(aa.__dict__)

__all__ = ['SetattTest', 'AttTestOne']
"""
__all__方法 裏面是 函數或 常量 或 類 的名字,一般在 __init__.py 文件中使用,在其他地方 通過 from df import * 時,只會導入 __all__裏的方法
"""

 

發佈了92 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章