通过字符串调用外部模块中的Python函数

acu*_*are 1 python genetic-programming python-import

我有一个手动维护的 python 函数和模块列表,将由遗传算法使用,我希望能够重复调用这些函数和模块并监视结果。

测试执行.py

import os
from random import randint

def main():
    toolList = [{'file':'test1.py', 'function':'sum_even_numbers', 'args':['list'], 'return':['int']},
                {'file':'test1.py', 'function':'get_min_even_num', 'args':['list'], 'return':['int']}   ]
    for tool in toolList:
        for i in range(0,3):
            run(tool, [randint(10,99) for j in range(1,randint(2,5))])

def run(tool, args):
    mod = __import__( os.path.basename(tool['file']).split('.')[0])
    func = getattr(mod, tool['function'])
    tool['return'] = func(args)
    print('main called ' + tool['file'] + '->' + tool['function'] + ' with ', args, ' = ', tool['return'])

main()
Run Code Online (Sandbox Code Playgroud)

测试1.py

def sum_even_numbers(numbers):
    return sum([i for i in numbers if i % 2 == 0])

def get_min_even_num(numbers):
    return min([i for i in numbers if i % 2 == 0])

# other code in test1.py which we dont want to execute
print('test1.py has been run' )
Run Code Online (Sandbox Code Playgroud)

代码的结果:

test1.py has been run
('main called test1.py->sum_even_numbers with ', [30, 66, 25, 45], ' = ', 96)
('main called test1.py->sum_even_numbers with ', [92], ' = ', 92)
('main called test1.py->sum_even_numbers with ', [59, 73], ' = ', 0)
('main called test1.py->get_min_even_num with ', [59, 12, 61, 24], ' = ', 12)
('main called test1.py->get_min_even_num with ', [22], ' = ', 22)
('main called test1.py->get_min_even_num with ', [97, 94], ' = ', 94)
Run Code Online (Sandbox Code Playgroud)

该代码通过字符串调用模块中的函数来工作,但在导入期间执行整个文件。有没有更好的方法来做到这一点,以便整个模块不运行?

roi*_*ppi 5

当您从模块导入某些内容时(即使是独立的模块级函数),Python 解释器必须先解析/编译整个文件,然后才能访问该函数。

对于 s 来说def,这是无害的 - 它们只是被编译成函数,没有造成任何损害。但有时您有“您不想运行的代码”,就像您print的示例中的那样。

导入模块时阻止代码执行的规范方法是:

if __name__ == '__main__':
    # code that only gets executed when I explicitly run this module
Run Code Online (Sandbox Code Playgroud)

多读书。