主程序以下: class Foo: def _inif(self,pname): self.pname = pname def func(): print('i'm func') def __getattr__(self, item): print('提示:屬性[%s]不存在。'%item) def __setattr__(selft, key, value): print('提示:屬性賦值操做:[%s=%s]'%(key,value)) self.__dict__[key]=value #self.key=value #沒法使用,會無限遞歸,這就是調用自己__setattr__ def __delattr__(self, item): print('提示:刪除屬性操做:刪除[%s]'%item) if item in self.__dict__: self.__dict__.pop(item) #del self.item #無限遞歸了 #沒法使用,會無限遞歸,這就是調用自己__delattr__
一、獲得屬性值。__getattr__方法的運行流程,以及getattr的運行流程。當不存在屬性名/方法名時,查找__getattr__()方法是否存在,存在即執行它。不存在再查看有沒有默認參數,有則返回,沒有則報錯。python
二、判斷屬性/方法名是否存在。__getattr__方法的運行流程,以及hasattr的運行流程函數
三、給屬性賦值。setattr(對象名, 屬性名字符串,屬性值),例如:setattr(f1,'y','ccc')。post
當__setattr__方法存在時,執行它內部的程序,必須執行:self.__dict__[key]=value,要否則不會進行賦值。(該方法默認返回值是None,通常不會使用)spa
四、刪除屬性。delattr(對象名, 屬性名字符串),例如:delattr(f1,'y')。code
當__delattr__方法存在時,執行它內部的程序,必須執行:對象
if item in self.__dict__:#要進行判斷,若是鍵不存在,pop會出錯。blog
self.__dict__.pop(item)遞歸
要否則不會進行刪除。(該方法默認返回值是None,通常不會使用)字符串
5.__getattribute__方法,只要調用屬性就會進行__getattribute__方法,只有遇到raise AttributeError()(必須是AttributeError異常)纔會執行__getattr__get
class Foo: def __init__(self, guestname, guestmobile): self.guestname = guestname self.guestmobile= guestmobile def __getattribute__(self, item): print('獲取屬性值操做 %s'%item) if item != 'guestname': raise AttributeError() def __getattr__(self, item): print('找不到屬性 %s'%item) f = Foo('小王','13945784807') f.guestname f.guestage
執行結果:
獲取屬性值操做 guestname
獲取屬性值操做 guestage
找不到屬性 guestage
6.操做對象的屬性/方法名時,像字典同樣操做__getitem__(),__setitem__(), __delitem__(),具體操做字典方法要在其中本身寫。如下代碼只列了setitem,其他的都操做self.__dict[xx]=xx就能夠。
class Foo: pass f =Foo() f['a']=12 執行結果: TypeError: 'Foo' object does not support item assignment
class Foo: def __setitem__(self, key, value): print('run setitem') self.__dict__[key]=value f =Foo() f['a']=12 print(f.a) 執行結果: run setitem 12
口訣:
對象/類的 點的操做,都和attr相關
對象/類的 中括號的操做,都和item相關
7.__str__和 __repr__,對象返回值的方法,他們內部必須以return返回,必須返回str類型的值。
a.當編譯器提示性返回時,就調用__repr__()
b.當print或者str(對象實例名),就調用__str__()
>>> class Foo: ... def __str__(self): ... return 'ggg' ... def __repr__(self): ... return 'xxx' ... >>> f = Foo() >>> f xxx >>> class Foo: ... def __str__(self): ... return 'ooo' ... >>> f=Foo() >>> f <__main__.Foo object at 0x000001AB94DC9C18> >>> print(f) ooo >>>
口訣:print()方法變量方法順序,找str,再找repr
''' str函數或者print函數--->obj.__str__() repr或者交互式解釋器--->obj.__repr__() 若是__str__沒有被定義,那麼就會使用__repr__來代替輸出 注意:這倆方法的返回值必須是字符串,不然拋出異常 '''