You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从子目录的文件中动态导入函数?

如何从子目录的文件中动态导入函数?

看起来你选对了用importlib做动态导入的路子,但遇到了两个小坑导致报错,我帮你一步步搞定~

第一个坑:别把.py后缀带进模块名里

看你的错误提示里出现了subfolder1.subfolder2.file1.py,这说明你输入文件名的时候大概率带了.py后缀!importlib.import_module需要的是模块名,不是完整的文件名,所以得确保输入的是file1而不是file1.py。

当然,为了更友好,你可以在代码里自动处理掉用户不小心输入的后缀:

file = input("Either file1 or file2").strip().removesuffix('.py')

这样不管用户输不带后缀的file1还是带后缀的file1.py,代码都能正常处理。

第二个坑:让子目录变成Python可识别的包

错误里还提到'subfolder1.subfolder2.file1' is not a package!,其实问题出在父目录没有被Python当作“包”。在Python中,要让一个目录被识别为包,只需要在目录里放一个空的__init__.py文件就行。

你需要在这两个目录里分别创建:

  • subfolder1/__init__.py(空文件就可以,不用写任何代码)
  • subfolder1/subfolder2/__init__.py(同样空文件就行)
    这样Python就会把这些目录当作合法的包,importlib就能正确找到里面的模块了。

优化后的完整代码

我帮你把代码再完善一下,加了输入验证和函数存在性检查,更健壮:

import importlib
import os

# 自动扫描subfolder2里所有可运行的文件(不用手动维护白名单!)
subfolder_path = os.path.join(os.path.dirname(__file__), "subfolder1", "subfolder2")
allowed_files = {
    f[:-3] for f in os.listdir(subfolder_path)
    if f.endswith(".py") and not f.startswith("_")  # 排除__init__.py和下划线开头的文件
}

file = input(f"Enter file name (choose from: {', '.join(allowed_files)}): ").strip().removesuffix('.py')

if file not in allowed_files:
    print(f"[ERROR] Invalid file! Choose from: {', '.join(allowed_files)}")
else:
    try:
        mod = importlib.import_module(f"subfolder1.subfolder2.{file}")
    except Exception as error:
        print(f"[ERROR] Failed to import module: {error}!")
    else:
        if hasattr(mod, "run"):
            mod.run()
        else:
            print(f"[ERROR] The file {file}.py doesn't have a 'run()' function!")

额外福利:自动适配新增文件

上面的代码已经实现了自动扫描subfolder2里的Python文件,以后你每天加新文件进去,完全不用修改主代码,也不用加if判断,程序自动就能识别并允许用户选择运行,完美匹配你的需求~

现在按照这个配置,创建好__init__.py文件,输入正确的文件名,就能顺利运行run函数啦!

备注:内容来源于stack exchange,提问作者GalaxyGamerYT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 15:47:59