You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Python中从嵌套目录结构导入函数并解决相关报错?

如何在Python中从嵌套目录结构导入函数并解决相关报错?

嗨,我来帮你理清楚这个问题,其实就是两个关键点没踩对,咱们一步步来解决:

首先说你遇到的第一个语法错误——这个完全是因为Python模块命名的规则:模块名不能包含连字符(-,你写的from a-a.b.c import ...里的a-a会被Python当成a - a(减法运算),这不就直接语法错了嘛,所以你把a-a改成a_a的思路是对的,但为啥又报模块找不到呢?

这是因为你漏了一个关键步骤:要让Python把这些目录识别为可导入的包,每个目录下都得放一个空的__init__.py文件,哪怕这个文件里啥内容都没有也行。

具体解决步骤:

  1. 先把目录名a-a改成a_a(遵循Python模块命名规范:只能用字母、数字、下划线)
  2. 给每个嵌套目录都添加空的__init__.py文件,最终的目录结构应该是这样:
    你的项目根目录/
    ├── test.py
    └── a_a/
        ├── __init__.py
        └── b/
            ├── __init__.py
            └── c/
                ├── __init__.py
                └── print.py
    
  3. 然后在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

火山引擎 最新活动