面向對象:反射、內置方法
阿新 • • 發佈:2018-03-03
是否 val urn 進行 subclass input 補充 sta 系列
反射:通過字符串映射到對象或者類的屬性
反射的方法:
class People: country = "China" def __init__(self,name,age): self.name = name self.age = age def talk(self): print("%s is talking" % self.name) obj = People("neo",22) """ 判斷是否擁有某個屬性: hasattr(o,name) # name是字符串格式 """ print(hasattr(obj,"name")) print(hasattr(obj,"talk")) print(hasattr(People,"country")) print(hasattr(People,"talk")) # 運行結果: # True # True # True # True """ 得到某個屬性的值: getattr(o,name,default) # default處寫上“None”,那麽即使沒有這個name程序也不會報錯 """ print(getattr(obj,"name",None)) print(getattr(obj,"talk",None)) print(getattr(obj,"gender",None)) print(getattr(People,"country",None)) print(getattr(People,"talk",None)) # 運行結果: # neo # <bound method People.talk of <__main__.People object at 0x00000035DB166668>> # None # China # <function People.talk at 0x000000878224BA60> """ 添加、修改某個屬性: setattr(object,"name",value) """ setattr(obj,"gender","male") setattr(obj,"name","NEO") print(obj.gender) print(obj.name) setattr(People,"nation","Han") print(People.__dict__) print(getattr(People,"nation",None)) print(People.nation) # 運行結果: # male # NEO # {‘__module__‘: ‘__main__‘, ‘country‘: ‘China‘, ‘__init__‘: <function People.__init__ at 0x00000018D460B9D8>, ‘talk‘: <function People.talk at 0x00000018D460BA60>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘People‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘People‘ objects>, ‘__doc__‘: None, ‘nation‘: ‘Han‘} # Han # Han """ 刪除某個屬性: delattr(o,name) """ delattr(obj,"age") print(obj.__dict__) delattr(People,"country") print(People.__dict__) # 運行結果: # {‘name‘: ‘NEO‘, ‘gender‘: ‘male‘} # {‘__module__‘: ‘__main__‘, ‘__init__‘: <function People.__init__ at 0x0000002C1C9BB9D8>, ‘talk‘: <function People.talk at 0x0000002C1C9BBA60>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘People‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘People‘ objects>, ‘__doc__‘: None, ‘nation‘: ‘Han‘}
反射的使用:
"""接收用戶輸入,觸發相應的功能""" class Service: def run(self): while True: # 輸入的是格式化的內容,如: get a.txt 或者 upload a.txt cmd = input(">>>").strip().split() # cmd = ["get","a.txt"] if hasattr(self,cmd[0]): func = getattr(self,cmd[0]) func(cmd) def get(self,cmd): print("get .......%s" %cmd[1]) def upload(self,cmd): print("upload ......%s" %cmd[1]) obj = Service() obj.run()
內置方法:
一、isinstance(obj,cls)和 issubclass(sub,super)
isinstance(obj,cls) # 檢查對象obj是否為 類 cls的對象 # 返回Bool值
issubclass(sub,super) # 檢測sub類是否為 super類的派生類(子類) # 返回Bool值
二、item系列: __getitem__(self, item)、__setitem__(self, key, value)、__delitem__(self, key)
"""通過item系列能夠把對象當做字典去處理""" class People: def __init__(self,name): self.name = name def __getitem__(self, item): print("get item test [%s]" %item) return self.__dict__.get(item) def __setitem__(self, key, value): print("set item test" ) self.__dict__[key] = value def __delitem__(self, key): print("del item test") self.__dict__.pop(key) # del self.__dict__[key] # 這種方式也可以 """下面討論這3中item在何種情況下被觸發""" p = People("neo") p["age"] # 對象["name"] 能夠觸發 __getitem__(self,item) # 跟__getitem__(self,item) 函數體的具體代碼無關 # 運行結果: # get item test [age] p["gender"] = "male" # 對象["key"] = "value" 能夠觸發 __setitem__(self,key,value) # 同樣, 與其函數體的具體代碼無關 print(p.__dict__) # 運行結果: # set item test # {‘name‘: ‘neo‘, ‘gender‘: ‘male‘} del p["name"] # del 對象["name"] 能夠觸發 __delitem__(self,key) # 與其函數體的具體代碼無關 # 運行結果: # del item test
三、 __str__(self) 方法:使打印對象的輸出結果格式化
""" __str__(self)方法:將print(object)的打印結果由對象的內存地址格式化成你需要的字符串形式,從而增加了打印結果的可讀性 print(object)觸發__str__(self), """ class People: def __init__(self,name,age): self.name = name self.age = age def __str__(self): print("=====>>>") return "aaa" # __str__只能返回字符串格式 # return "<name:%s> <age:%s>"%(self.name,self.age) # 可以自己定義打印結果的格式 p = People("neo",18) print(p) # 打印對象能夠觸發__str__(self) # 運行結果: # =====>>> # aaa
四、__del__ 方法
補充知識:
# 以open(file)為例 f = open("setting.py") # python沒有能力自己打開硬盤文件,打開文件的動作需要操作系統去完成,所以 open其實是個命令:告訴操作系統讓它打開a.txt這個文件;這個賦值過程涉及兩方面的資源:變量f 是應用程序的資源,open("setting.py"):打開硬盤文件是操作系統的資源 f.read() # read()也是一個命令,是讓操作系統讀取文件內容 # read()需要在文件關閉之前進行 """ 資源不能一直被占用;python只能回收它自己應用程序的資源(例如python程序結束後資源都會被回收),但python沒有能力回收操作系統的資源,所以在python程序結束前一定要關閉掉文件 """ f.close() # close()也是一個對操作系統發出的命令,讓操作系統關閉掉硬盤上的文件,並把操作系統裏面相應的資源回收;註意:python程序結束前一點要關閉掉文件,這一點不要忘 """ 雖然硬盤文件已經關閉掉,但f 還能夠打印,因為f 是應用程序的資源;但文件關閉後就不能再read了 """ print(f) # 打印結果: # <_io.TextIOWrapper name=‘setting.py‘ mode=‘r‘ encoding=‘cp936‘>
__del__(self) 的作用: 讓操作系統回收掉自己的資源
觸發情況:1. del f # del file(file是個對象,如上面示例中的f)能夠自動調用類內部的 __del__(self) (先觸發__del__再刪除f這個對象)
2. 如果沒有del f,那麽在程序結束的之前會自動調用__del__(self)(或者說在程序運行到最後已經沒有其他代碼要執行了) (也是python先觸發__del__,再刪除python自己的f)
總結: 在類內部定義的內置方法都是綁定給對象的;而且在某種情況下會自動被觸發調用
附: 其他內置方法可參考鏈接: http://www.cnblogs.com/linhaifeng/articles/6204014.html
面向對象:反射、內置方法