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__裏的方法 """