Python自动导入文件函数到字典时结果与手动赋值不符问题
问题说明
尝试仅从其他文件导入全局函数时,手动构建的函数字典与自动生成的字典返回值不一致。初步判断values_automated字典中存储的是字符串类型的函数名,而非实际的函数对象,不清楚如何获取函数引用并存入变量。
复现代码
value_by_hand = { "function_1": function_1, "function_2": function_2 } values_automated = {} with open("file.py") as f: for text in f.readlines(): if text[0] == "d": text = text.strip() texts = text.replace("def ", "") texts = texts.replace("():", "") values_automated[texts] = texts print(value_by_hand) print(values_automated)
运行输出
{'function_1': <function function_1 at 0x101a1a110>, 'function_2': <function function_2 at 0x101a2a1b0>} {'function_1': 'function_1', 'function_2': 'function_2'}
问题原因
当前自动生成字典的逻辑只是读取file.py的文本内容做字符串替换,最终存入字典的是解析出来的函数名字符串,既没有把目标文件加载到Python运行环境,也没有获取到对应名称的函数对象引用,自然和手动存入函数对象的字典结构不一致。
另外这种纯字符串解析的逻辑鲁棒性很差:如果函数带参数、def关键字前有缩进、行尾带注释,都会解析失败。
解决方法
不需要手动解析文件文本,直接通过Python的模块加载机制导入目标文件,再从模块属性中筛选函数对象即可。
- 常规场景直接用import导入目标模块,配合inspect筛选模块内自定义的全局函数:
import inspect # 直接导入目标file.py文件 import file values_automated = {} for name, obj in inspect.getmembers(file): # 过滤出当前模块自己定义的函数,排除导入的其他依赖 if inspect.isfunction(obj) and obj.__module__ == file.__name__: values_automated[name] = obj
- 如果需要动态指定文件路径、不想硬编码import语句,可以用importlib动态加载模块后再提取函数:
import inspect import importlib.util # 按需替换为实际的文件路径 file_path = "./file.py" spec = importlib.util.spec_from_file_location("target_file", file_path) target_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(target_module) values_automated = {} for name, obj in inspect.getmembers(target_module): if inspect.isfunction(obj) and obj.__module__ == target_module.__name__: values_automated[name] = obj
两种方式生成的字典和手动构建的value_by_hand结构完全一致,value均为可直接调用的函数对象,不受代码格式变动影响。
内容的提问来源于stack exchange,提问作者Brandon
相关产品推荐
相关产品推荐

