如何在Python中从嵌套目录结构导入函数并解决相关报错?
如何在Python中从嵌套目录结构导入函数并解决相关报错?
嗨,我来帮你理清楚这个问题,其实就是两个关键点没踩对,咱们一步步来解决:
首先说你遇到的第一个语法错误——这个完全是因为Python模块命名的规则:模块名不能包含连字符(-),你写的from a-a.b.c import ...里的a-a会被Python当成a - a(减法运算),这不就直接语法错了嘛,所以你把a-a改成a_a的思路是对的,但为啥又报模块找不到呢?
这是因为你漏了一个关键步骤:要让Python把这些目录识别为可导入的包,每个目录下都得放一个空的__init__.py文件,哪怕这个文件里啥内容都没有也行。
具体解决步骤:
- 先把目录名
a-a改成a_a(遵循Python模块命名规范:只能用字母、数字、下划线) - 给每个嵌套目录都添加空的
__init__.py文件,最终的目录结构应该是这样:你的项目根目录/ ├── test.py └── a_a/ ├── __init__.py └── b/ ├── __init__.py └── c/ ├── __init__.py └── print.py - 然后在
test.py里用正确的导入语句,这里给你几种常用的写法:- 导入指定的单个/多个函数(推荐,清晰不混乱)
from a_a.b.c.print import print_5, print_10 print_5() # 直接调用函数 - 导入整个模块,通过模块名调用函数
from a_a.b.c import print as print_module # 这里用as重命名是避免和内置的print冲突 print_module.print_5() - 一次性导入模块里所有函数(不推荐,容易和其他变量/函数重名)
from a_a.b.c.print import * print_5()
- 导入指定的单个/多个函数(推荐,清晰不混乱)
如果你实在不想改a-a这个目录名(比如有特殊需求)
可以用importlib来动态导入,不过这种写法比较繁琐,还是改名的方案更规范:
import importlib.util import os import sys # 把a-a目录添加到Python的模块搜索路径里 sys.path.append(os.path.abspath('a-a')) # 定位到print.py文件 spec = importlib.util.spec_from_file_location("b.c.print", os.path.abspath("a-a/b/c/print.py")) # 加载模块 print_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(print_module) # 调用函数 print_module.print_5()
再回头说你之前的错误:
- 语法错误:完全是连字符的锅,Python把
a-a当成了减法表达式,直接语法不通过 - 模块找不到:改了名字但没加
__init__.py,Python不认为a_a是一个可导入的包,所以找不到模块
备注:内容来源于stack exchange,提问作者Hemant Bhargava




