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

Python子目录导入行为不一致问题及解决方案

Python模块导入兼容问题:同时运行子模块文件与父目录入口文件

问题场景

文件结构:

a.py
module/b.py
module/c.py

各文件内容:

  • a.py:
from module.b import hello

hello()
  • b.py:
from c import helloworld

def hello():
    helloworld()

hello()
  • c.py:
def helloworld():
    print("Hello world")

执行结果差异:

  • 进入module目录运行python b.py,正常输出Hello world
  • 在父目录运行python a.py,抛出ModuleNotFoundError: No module named 'c'

问题原因

Python的模块搜索路径(sys.path)在两种执行场景下存在差异:

  1. 直接运行b.py时,Python会将**当前执行目录(即module/)**加入sys.path,因此能直接找到同目录的c.py
  2. 通过a.py导入module.b时,Python的sys.path是父目录,此时c.py不在搜索路径范围内,导致无法找到模块

极简解决方案

方案1:相对导入+入口判断

修改b.py,根据执行场景切换导入方式:

# 修改后的b.py
if __name__ == "__main__":
    # 直接运行时,用当前目录的导入方式
    from c import helloworld
else:
    # 被其他模块导入时,用相对导入定位同包内的c模块
    from .c import helloworld

def hello():
    helloworld()

if __name__ == "__main__":
    hello()

这样既适配直接运行b.py的场景,也能满足a.py导入module.b的需求。

方案2:统一添加搜索路径

修改b.py,将自身所在目录强制加入模块搜索路径:

# 修改后的b.py
import sys
from pathlib import Path

# 把当前文件所在的module目录加入搜索路径
sys.path.append(str(Path(__file__).parent))

from c import helloworld

def hello():
    helloworld()

if __name__ == "__main__":
    hello()

这种方式无需区分执行场景,不管是直接运行还是被导入,Python都能找到c模块。

额外说明

可以给module目录添加空的__init__.py文件,将其标记为正式Python包,但上述方案不依赖该文件也能正常生效。

内容的提问来源于stack exchange,提问作者Rolf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:43:13