python之路(9)反射、包裝類、動態模組匯入
阿新 • • 發佈:2018-11-21
目錄
反射
python提供自省的四個方法:
hasattr(object,name) 判斷object中有沒有有個name字串對應對應的方法和屬性
class demo: name = 'chen' age = '22' def test_func(self): print("存在") hasattr(demo, 'test_func') #True hasattr(demo, 'name') #True hasattr(demo, 'date') #False
(常用)getattr(object,name,default=None) 根據name字串尋找object中對應的資料屬性或函式屬性,相當於object.name
class demo: name = 'chen' age = '22' def test_func(self): print("存在") getattr(demo, 'test_func') #<function demo.test_func at 0x00000264F0ABA9D8> getattr(demo, 'name') #chen getattr(demo, 'date') #報錯
setattr(object,name,value) 根據name字串去設定或修改object中相對應的資料屬性或函式屬性,相當於object.name=value
class demo: name = 'chen' age = '22' def test_func(self): print("存在") #設定資料屬性 setattr(demo,'date','2018/11/21') print(getattr(demo, 'date')) #2018/11/21 #設定函式屬性 setattr(demo,'test2_func',lambda x:x+2) print(getattr(demo, 'test2_func')(8)) #10
delattr(object,name) 根據name字串去刪除object中相對應的資料屬性或函式屬性,相當於del object.name
class demo: name = 'chen' age = '22' def test_func(self): print("存在") delattr(demo,'name')
反射使用類中用到的三個內建函式
(常用)_getattr_ 當訪問的屬性找不要的時候執行這個這個函式
class demo: def __init__(self,name,age): self.name = name self.age = age def __getattr__(self, item): print("不存在%s屬性"%item) d1 = demo('chen',22) #呼叫不存在的屬性 d1.data #不存在data屬性
_setattr_ 當賦值屬性值時執行這個函式
class demo: def __init__(self,name,age): self.name = name #賦值操作 self.age = age #賦值操作 def __setattr__(self, key, value): print("key:%s value:%s"%(key,value)) self.__dict__[key]=value d1 = demo('chen',22) #key:name value:chen key:age value:22
_delattr_ 當刪除屬性事執行這個函式
class demo: def __init__(self,name,age): self.name = name #賦值操作 self.age = age #賦值操作 def __delattr__(self, item): print("刪除%s"%item) self.__dict__.pop(item) d1 = demo('chen',22) del d1.name #刪除name
變數賦值操作的自定製之所有字串大寫
class demo: def __init__(self,name,age): self.name = name #賦值操作 self.age = age #賦值操作 def __setattr__(self, key, value): if type(value) is str: self.__dict__[key] = value.upper() #制定大寫 else: self.__dict__[key] = value d1 = demo('chen',22) print(d1.__dict__) #{'name': 'CHEN', 'age': 22}
利用繼承二次包裝標準類
class List(list): def append(self, value): if type(value) is str: super().append(value) else: print('只能新增字串型別') def show_midlle(self): #求列表中間的value mid_index=int(len(self)/2) return self[mid_index] l1=List('chen') l1.append(12) #只能新增字串型別 l1.show_midlle() #e
利用授權二次包裝標準類
授權也是一種包裝,但不是通過繼承去實現,利用_getattr_實現
import time class FileHandle: def __init__(self,filename,mode='r',encoding='utf-8'): #已實現的功能,依然用原來的功能 self.file=open(filename,mode,encoding=encoding) # 定製在寫入檔案時,寫入時間的寫函式 def write(self,line): t=time.strftime('%Y-%m-%d %X') self.file.write('%s %s' %(t,line)) #如果訪問的屬性不純在 def __getattr__(self, item): return getattr(self.file,item) f1=FileHandle('a.txt','w+',encoding='utf-8') f1.write('第一條\n') f1.write('第二條\n') f1.write('第三條\n')
2018-11-21 19:11:07 第一條 2018-11-21 19:11:07 第二條 2018-11-21 19:11:07 第三條
動態匯入模組
# 匯入的是m1,不是m1下的t檔案 # 這樣匯入的是路徑最頂層的模組 module_t = __import__('m1.t') # print(module_t) #<module 'm1' (namespace)> module_t.t.test3() #這裡是t模組 #利用模組匯入 import importlib #匯入的是m1下的t檔案 m = importlib.import_module("m1.t") print(m) # <module 'm1.t' from 'F:\\PyCharm 2018.2.3\\PycharmProjects\\chen\\day13\\m1\\t.py'> m.test3() #這裡是t模組