Python如何导入模块所有函数存入列表 适配可变数量函数遍历调用
可行实现方案
你原有的计时测试思路本身没有逻辑错误,只是对Python模块导入的规则不熟悉,不需要推翻原有设计,选以下任意一种方案,都能实现无需修改main.py、适配单题可变数量解法函数的需求。
方案1:自动扫描模块内的自定义函数
不需要修改任何已有的题目解法文件,直接导入整个题目模块,借助Python标准库inspect过滤出当前题目文件内定义的所有函数即可,main.py示例代码:
import inspect import problem1 # 过滤规则:只保留problem1模块内自定义的函数,自动排除内置属性、导入的其他模块/第三方库对象 func_list = [ obj for name, obj in inspect.getmembers(problem1) if inspect.isfunction(obj) and obj.__module__ == problem1.__name__ ] # 遍历运行所有解法 test_arg = 你的测试入参 for func in func_list: print(f"运行解法:{func.__name__}") func(test_arg)
这个方案的特点:
- 零侵入,完全不需要改动已有的题目解法文件
- 自动识别新增的解法函数,写完函数不需要做额外登记就会被自动加入测试队列
- 存在小缺陷:如果题目文件里写了生成测试用例、数据处理之类的辅助函数,会被误识别为解法函数加入测试,需要给辅助函数加下划线前缀或者额外写过滤规则排除
方案2:解法文件主动暴露测试函数列表(更推荐)
如果题目文件里包含非解法的辅助函数,优先用这个方案,可控性更高。只需要在每个题目的解法文件末尾,手动声明要参与测试的函数列表即可,比如在problem1.py末尾加:
# 所有需要跑计时测试的解法函数都放进这个列表 test_funcs = [func1, func2, func3]
对应的main.py代码非常简单,不需要做任何过滤:
import problem1 test_arg = 你的测试入参 for func in problem1.test_funcs: print(f"运行解法:{func.__name__}") func(test_arg)
这个方案的特点:
- 可控性极强,只会运行你主动加入列表的解法,完全不会误跑辅助逻辑
- 写法简单,不需要依赖额外的标准库,代码可读性高
- 新增解法时,只需要把新函数名加进同文件的
test_funcs列表即可,main.py全程不需要修改
扩展优化:动态切换题目无需改main
如果需要频繁切换不同题号的题目做测试,可以借助标准库importlib动态加载对应模块,连导入模块的代码都不需要反复修改:
import importlib import inspect # 只需要修改这个题号变量,就能自动加载对应的problemX.py文件 CURRENT_PROBLEM = 1 problem_mod = importlib.import_module(f"problem{CURRENT_PROBLEM}") # 可以搭配方案1的自动扫描逻辑 func_list = [ obj for name, obj in inspect.getmembers(problem_mod) if inspect.isfunction(obj) and obj.__module__ == problem_mod.__name__ ] # 也可以搭配方案2的主动暴露逻辑,直接使用problem_mod.test_funcs即可 test_arg = 你的测试入参 for func in func_list: print(f"运行解法:{func.__name__}") func(test_arg)
关于之前尝试的无效写法说明
Python不支持from xxx import * as func_list语法,本质是官方不鼓励import *的导入方式:这种写法会把模块内所有非下划线开头的成员全部注入当前命名空间,很容易引发命名冲突,也会让代码依赖关系变得不清晰,实际开发中除了少数特殊场景,都不推荐使用。直接导入模块本身、再通过模块属性访问内部成员,才是Python推荐的常规用法。
内容的提问来源于stack exchange,提问作者Cobalt336
相关产品推荐
相关产品推荐

