1. 程式人生 > >python動態呼叫函式

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
中有哪些屬性、類、函式 #呼叫引入py檔案中的類中的函式 test2_func = getattr(ip_module, "test2")#獲取test2函式 test2_func('test2_name')#呼叫並傳遞引數
['__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test2']
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

以上程式碼均都經過自己測試執行,如果有問題請留言。大家一起學習,一起進步