反射實操與面向物件雙下方法
阿新 • • 發佈:2022-04-11
反射實操
利用面向物件的反射編寫系統終端
反射提供了一種不考慮程式碼,對資料和功能進行操作的方式
class WinCmd(object): # 定義一個WinCmd的類 def ls(self): print('windows ls命令') def dir(self): print('windows dir命令') def cd(self): print('windows cd命令') class Linux(object): # # 定義一個Linux的類 def ls(self): print('linux ls命令') def dir(self): print('linux dir命令') def cd(self): print('linux cd命令') obj1 = WinCmd() # 生成物件 print(obj1) # <__main__.WinCmd object at 0x0000017B0E7A23C8> obj2 = Linux() # 生成物件 print(obj2) # <__main__.Linux object at 0x0000017B0E7A2470> def run(obj): while True: cmd = input('cmd order>>>: ').strip() # 獲取使用者命令 if hasattr(obj, cmd): # 如果物件的名稱空間有該字串所對應的資料或者功能,結果為True func_name = getattr(obj, cmd) # 如果物件的名稱空間有該字串所對應的資料或者功能,取其對應的資料或者功能 func_name() else: print('cmd order is not be found') run(obj1) # 類似於win的cmd命令 run(obj2) # 類似linux的命令視窗
面向物件部分雙下方法(內建方法)
面向物件中有一些方法名字是類似於__……__
的結構。這類方法也被人稱為魔法方法。因為有些雙下方法是不需要呼叫的,而是在特殊條件下自動觸發的。比如__init__
方法會在物件例項化的時候自動觸發。
class MyClass(object): person: True def __init__(self, name, age, gender): # 物件例項化 self.name = name self.age = age self.gender = gender def __str__(self): # 物件展示的時候自動觸發 print('列印操作') return 'print' def __del__(self): # 主動或者被動(執行結束,垃圾處理機制作用)刪除物件的時候觸發 print('刪除操作') pass def __getattr__(self, item): # 獲取資料或者功能,找不到時觸發 print('愛而不得') pass def __call__(self, *args, **kwargs): # 物件被加括號呼叫的時候觸發 print('呼叫物件') pass def __enter__(self): # with方法操作物件時觸發 print('檔案管理操作') pass def __exit__(self, exc_type, exc_val, exc_tb): # 結束操作物件時觸發 print('檔案管理操作結束') pass def __getattribute__(self, item): # 查詢資料或功能時觸發,無論能不能找到 print('大膽愛') pass '''在__getattr__方法和__getattribute__方法同時存在時,後者會頂替前者執行作用,前者不執行''' obj1 = MyClass('oliver', 25, 'male') print(obj1) '''釋放__getattr__方法,注掉__getattribute__方法''' obj1.name # 能獲取到 obj1.salary # 獲取不到 愛而不得 (__gertattr__) '''釋放__getattribute__方法,注掉__getattr__方法''' obj1.name # 大膽愛 obj1.salary # 大膽愛 '''釋放__getattribute__方法,__getattr__方法''' obj1.name # 大膽愛 obj1.salary # 大膽愛 '''在__getattr__方法和__getattribute__方法同時存在時,後者會頂替前者執行作用,前者不執行''' obj1() # 呼叫物件 with obj1 as f: print('進行檔案操作') # 檔案管理操作(__enter__) 進行檔案操作 檔案管理操作結束(__exit__)
更多方法:面向物件更多雙下方法
問題處理
問題一: 使字典具備句點符取值的功能
class MyDict(dict): def __getattr__(self, item): # 取物件中的名字是'item'的資料或者方法 return self.get(item) # 獲得該名字所對應的資料或者功能名 def __setattr__(self, key, value): # 在名稱空間中新增資料 self[key] = value # 以鍵值對的方式新增 obj1 = MyDict('oliver', 25) print(obj1) # {'name': 'oliver', 'age': 25} print(obj1.name) # oliver print(obj1.age) # 25 obj1.gender = 'male' # 通過點的方式對物件的名稱空間進行操作,新增資料 print(obj1) # {'name': 'oliver', 'age': 25, 'gender': 'male'} print(obj1.salary) # None
問題二:程式碼補全問題
'''
題目:
class Context:
pass
with Context() as ctx:
ctx.do_something()
'''
'''
解決步驟:
分析:
類 Context -----> Context():產生物件 -----> with 操作 Context():需要有 __enter__ 和__exit__
-----> ctx.do_something() 物件用點的方式訪問do_something,且do_something加了括號,所以物件有
do_something方法
'''
class Context:
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
return 123
def do_something(self):
print('程式碼已補全')
with Context() as ctx:
ctx.do_something() # 程式碼已補全