Python開發基礎----反射、物件導向進階

來源:互聯網
上載者:User

標籤:反射   ...   設定   對象   getattr   __del__   nbsp   使用者   property   

isinstance(obj,cls)和issubclass(sub,super)

isinstance(obj,cls)檢查是否obj是否是類 cls 的對象,如果是返回True

1 class Foo(object):2     pass3 obj = Foo()4 print(isinstance(obj, Foo))

issubclass(sub, super)檢查sub類是否是 super 類的衍生類別,如果是返回True

1 class Foo(object):2     pass 3 class Bar(Foo):4     pass5 issubclass(Bar, Foo)

反射

反射主要是指程式可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。

python物件導向中的反射:通過字串的形式操作對象相關的屬性。而python中的一切事物都是對象,即都可以使用反射。

範例程式碼:

1 class Teacher:2     school=‘jialidun‘3     def __init__(self,name,age):4         self.name=name5         self.age=age6     def teach(self):7         print(‘%s teach‘ %self.name)

通過字串的方式判斷是否存在一個屬性:

1 t=Teacher(‘bob‘,18)2 print(hasattr(Teacher,‘name‘))  #False3 print(hasattr(Teacher,‘school‘))    #True4 print(hasattr(Teacher,‘teach‘))     #True5 print(hasattr(t,‘name‘))  #True6 print(hasattr(t,‘school‘))    #True7 print(hasattr(t,‘teach‘))     #True

通過字串的方式擷取一個屬性:

1 print(getattr(Teacher,‘school‘))    #擷取到則返回屬性的值2 print(getattr(Teacher,‘sdfad‘,None))    #擷取不到返回None,如果不指定None那麼拋出異常錯誤

通過字串的方式設定一個屬性:

1 setattr(Teacher,‘sex‘,‘male‘)    #設定Teacher類的屬性sex=‘male‘2 setattr(t,‘sex‘,‘female‘)    #設定對象t對象的屬性sex=‘female‘3 print(Teacher.__dict__)4 print(t.__dict__)

通過字串的方式刪除一個屬性:

1 delattr(Teacher,‘sex‘)2 delattr(t,‘sex‘)

反射應用情境:使用者互動

 1 class Cmd: 2     def __init__(self,name): 3         self.name=name 4     def run(self): 5         while True: 6             cmd=input(‘>>>‘).strip() 7             if not cmd:continue 8             if hasattr(self,cmd):    #判斷這個類包含不包含輸入的屬性 9                 func=getattr(self,cmd)    #如果包含,擷取該屬性10                 func()    #執行該屬性(輸入name會拋錯提示字串不能被調用,因為name是一個資料屬性,而非函數屬性)11             else:12                 print(‘not valid func‘)13     def ls(self):14         print(‘ls function‘)15     def pwd(self):16         print(‘pwd function‘)17     def cat(self):18         print(‘cat function‘)19 c=Cmd(‘bob‘)20 c.run()

反射的好處

實現可插拔機制:可以事先定義好介面,介面只有在被完成後才會真正執行,這實現了隨插即用,這其實是一種‘後期綁定’,即可以事先把主要的邏輯寫好(只定義介面),然後後期再去實現介面的功能

動態匯入模組:基於反射當前模組成員

__str__方法

改變對象的字串顯示

 1 class Teacher: 2     def __init__(self,name,age): 3         self.name=name 4         self.age=age 5 t=Teacher(‘bob‘,18) 6 print(t) 7 輸出結果 8 <__main__.Teacher object at 0x0000020FC4DA9278> 9 10 #########分割線君###########11 12 class Teacher:13     def __init__(self,name,age):14         self.name=name15         self.age=age16     def __str__(self):17         return ‘<name:%s age:%s>‘ % (self.name, self.age)18 t=Teacher(‘bob‘,18)19 print(t)    #t.__str__()20 輸出結果:類中的__str__函數的執行結果21 <name:bob age:18>

__del__方法

在程式執行完了之後會自動執行的內容

 1 class Foo: 2     def __init__(self,x): 3         self.x=x 4     def __del__(self): 5         print(‘執行__del__‘) 6         ‘‘‘一般用來做一些關於對象執行完了之後剩下的垃圾的清理操作‘‘‘ 7 f=Foo(10) 8 print(‘執行完了‘) 9 10 輸出結果:先執行最後的print,沒有代碼了執行__del__函數11 執行完了12 執行__del__

刪除對象後立即執行的內容

 1 class Foo: 2     def __init__(self,x): 3         self.x=x 4     def __del__(self): 5         print(‘執行__del__‘) 6         ‘‘‘做一些關於對象的清理操作‘‘‘ 7 f=Foo(10) 8 del f     #刪除的時候也會執行del內容 9 print(‘執行完了‘)10 11 輸出結果:刪除了f對象後執行了__del__後才執行最後的print12 執行__del__13 執行完了

item系列

以中括弧的方式進行處理類似於:

1 l=[‘a‘,‘b‘,‘c‘]2 dic={‘a‘:1}3 print(l[1])4 print(dic[‘a‘])

__getitem__、__setitem__、__delitem__

 1 class Teacher: 2     def __init__(self,name,age,sex): 3         self.name=name 4         self.age=age 5         self.sex=sex 6     def __getitem__(self, item):    #查詢 7         # return getattr(self,item) 8         return self.__dict__[item] 9     def __setitem__(self, key, value):    #設定10         # setattr(self,key,value)11         self.__dict__[key]=value12     def __delitem__(self, key):    #刪除13         # delattr(self,key)14         self.__dict__.pop(key)15 f=Teacher(‘bob‘,18,‘male‘)16 print(f.name) #f[‘name‘]17 print(f[‘name‘])    #查詢18 f[‘name‘]=‘bob_nb‘    #設定19 print(f.__dict__)20 del f[‘name‘]    #刪除21 print(f.__dict__)

__len__方法

給對象提供len()統計方法

1 class Teacher:2     def __init__(self,name,age,sex):3         self.name=name4         self.age=age5         self.sex=sex6     def __len__(self):    #長度設定為107         return 108 f=Teacher(‘bob‘,18,‘male‘)9 print(len(f))    #輸出10

 

其他方法(補充)

__setattr__,__delattr__,__getattr__方法

 1 class Foo: 2     x=1 3     def __init__(self,y): 4         self.y=y 5     def __getattr__(self, item): 6         print(‘----> from getattr:你找的屬性不存在‘) 7     def __setattr__(self, key, value):  #限制賦值,無法對屬性直接賦值,必須要對__dict__進行操作賦值 8         print(‘----> from setattr‘) 9         # self.key=value #這就無限遞迴了,任何賦值操作都會調用__setattr__的運行,所以....10         # self.__dict__[key]=value #應該使用這種方式,操作字典可以賦值成功11     def __delattr__(self, item):12         print(‘----> from delattr‘)13         # del self.item #無限遞迴了,同__setattr__方法的無限遞迴14         self.__dict__.pop(item)15 #__setattr__添加/修改屬性會觸發它的執行16 f1=Foo(10)17 f1.__setattr__(‘a‘,1)   #不是直接操作字典,無法賦值18 print(f1.__dict__) # 因為重寫了__setattr__,凡是賦值操作都會觸發它的運行,什麼都不寫,就是根本沒賦值,除非直接操作屬性字典,否則永遠無法賦值19 f1.z=320 print(f1.__dict__)21 #__delattr__刪除屬性的時候會觸發22 f1.__dict__[‘a‘]=3#我們可以直接修改屬性字典,來完成添加/修改屬性的操作23 del f1.a    #刪除的時候如果上面函數是del self.item,會無限遞迴24 print(f1.__dict__)25 26 #__getattr__只有在使用點調用屬性且屬性不存在的時候才會觸發27 f1.xxxxxx

封裝(對標準資料類型進行方法修改)

通過繼承和派生的方式,進行修改源生資料類型的方法

 1 class List(list): #繼承list所有的屬性,也可以派生出自己新的,比如append和mid 2     def append(self, p_object): 3         ‘派生自己的append:加上類型檢查‘ 4         if not isinstance(p_object,int): 5             raise TypeError(‘must be int‘) 6         super().append(p_object) 7     @property 8     def mid(self): 9         ‘新增自己的屬性‘10         index=len(self)//211         return self[index]

Python開發基礎----反射、物件導向進階

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.