python動態呼叫函式
會java的開發人員都知道java中動態呼叫一個類中的方法都是使用反射機制,動態載入class(包名+類名+'.class')獲取類物件,然後再獲取method,再呼叫對應方法等
但是python中在一個py檔案中,不通過from...import來引入另一個py,然後呼叫其中的函式呢?
廢話不多說,直接上程式碼:
檔案目錄為:
mytest1.py:
class Test1: def test1(self, name): print("this is my_test1.py class Test1 func is test1 args is %s" % name) def test2(self, name): print("this is my_test2.py class Test1 func is test2 args is %s" % name) def test2(name): print("this is my_test1.py func is test2 args is %s" % name)
我想在test_main.py中呼叫my_test1.py中的test2方法,並傳遞name引數
test_main.py
#使用__import__ ip_module = __import__('my_test1') print(dir(ip_module))#檢視my_test1['__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test2']中有哪些屬性、類、函式 #呼叫引入py檔案中的類中的函式 test2_func = getattr(ip_module, "test2")#獲取test2函式 test2_func('test2_name')#呼叫並傳遞引數
this is my_test1.py func is test2 args is test2_name
這樣就可以呼叫啦
但是,如果我在my_test1.py中Test1類中的test1()方法呢?如下:
ip_module = __import__('my_test1') test1_class = getattr(ip_module, "Test1") test1_obj = test1_class() test1_func = getattr(test1_obj, 'test1') test1_func("test1_name")
執行結果:
this is my_test1.py class Test1 func is test1 args is test1_name
當然,我也可以迴圈遍歷Test1下的所有方法:
for attr in dir(test1_obj): if attr[0] != '_': class_attr_obj = getattr(test1_obj, attr) if hasattr(class_attr_obj, '__call__'): class_attr_obj('aa') else: print(attr, ' type:', type(class_attr_obj), ' value:', class_attr_obj)
這樣會把Test1下的所有方法都呼叫一遍
this is my_test1.py class Test1 func is test1 args is aa
this is my_test2.py class Test1 func is test2 args is aa
另外還可以用另一種方式,需要依賴 importlib
import importlib my_test1_module = importlib.import_module('my_test1', ".") my_test1_func_test2 = getattr(my_test1_module,"test2") my_test1_func_test2("my_test1_func_test2")#呼叫my_test1中的test2方法 非Test1類中的 my_test1_cls = getattr(my_test1_module, "Test1") cls_obj = my_test1_cls() my_test1_test1 = getattr(cls_obj, 'test1') my_test1_test1('my_test1_test1')#呼叫Test1中的test1方法 my_test1_test2 = getattr(cls_obj, 'test2') my_test1_test2('my_test1_test2')#呼叫Test1中的test2方法
執行:
this is my_test1.py func is test2 args is my_test1_func_test2
this is my_test1.py class Test1 func is test1 args is my_test1_test1
this is my_test2.py class Test1 func is test2 args is my_test1_test2
如果我在test_1包下建立了my_test2.py,程式碼如下:
class Test2: def test1(self, name): print("this is test_1.my_test2.py class Test2 func is test1 args is %s" % name) def test2(self, name): print("this is test_1.my_test2.py class Test2 func is test2 args is %s" % name) def test2(name): print("this is test_1.my_test2.py func is test2 args is %s" % name)
那麼,我想在test_main.py下呼叫my_test2該如何呼叫呢?
其實很簡單,只需要載入的時候加上包名就可以了
import importlib my_test1_module = importlib.import_module('test_1.my_test2', ".") my_test1_func_test2 = getattr(my_test1_module,"test2") my_test1_func_test2("my_test1_func_test2")#呼叫my_test1中的test2方法 非Test1類中的 my_test1_cls = getattr(my_test1_module, "Test2") cls_obj = my_test1_cls() my_test1_test1 = getattr(cls_obj, 'test1') my_test1_test1('my_test1_test1')#呼叫Test1中的test1方法 my_test1_test2 = getattr(cls_obj, 'test2') my_test1_test2('my_test1_test2')#呼叫Test1中的test2方法
結果如下:
this is test_1.my_test2.py func is test2 args is my_test1_func_test2
this is test_1.my_test2.py class Test2 func is test1 args is my_test1_test1
this is test_1.my_test2.py class Test2 func is test2 args is my_test1_test2
以上程式碼均都經過自己測試執行,如果有問題請留言。大家一起學習,一起進步