Python模块中的绝对导入失败

6 投票
2 回答
3995 浏览
提问于 2025-04-17 06:25

我有一个项目,结构大概是这样的:

my_project/
          __init__.py -- empty
          run.py
          datacheck/
                  __init__.py -- empty
                  datacheck.py -- containing class DataCheck(object)
                  config.py -- containing BusinessConfig(object)
                  business.py -- containing class BusinessCheck(DataCheck)

我的 PYTHONPATH 设置里包含了 /my_project 这个路径。

在 run.py 文件里,我写了以下代码:

from datacheck.business import BusinessCheck
business = BusinessCheck()
business.check_data()

在 business.py 文件中,我有一些导入语句,但这些导入失败了:

from datacheck.config import BusinessConfig
from datacheck.datacheck import DataCheck

from .config import BusinessConfig 这样的相对导入是可以用的,不过我在很多讨论中看到,大家都说绝对导入更好。

为了做个简单的测试,我还创建了以下文件:

myproject/
          __init__.py -- empty
          run_test.py
          test/
              __init__.py -- empty
              test1.py -- containing class Test1(object)
              test2.py -- containing class Test2(Test1)

run_test.py 文件导入并运行了 Test2 类,这个没有出错。

这让我有点困惑,我不明白为什么在 datacheck 中我的绝对导入不成功——有没有人能解释一下?

2 个回答

2

我知道这已经是很多年前的事了,但为了帮助其他在这里寻找答案的人,我用这段代码解决了一个类似的问题:

from __future__ import absolute_import

之后,在Python 2.6和2.7中,绝对导入就正常工作了。

8

如果你的模块可以作为 __main__ 来使用,建议你使用绝对导入,具体可以参考文档。如果不能,那使用相对导入也没问题。

这些导入会失败,因为你的包 datacheck 里面有一个同名的模块 datacheck。当 Python 查找这个名字时,它会先在包里面找。结果它找到了模块 datacheck,但是这个模块里面没有 config 这个名字,所以导入就失败了。

如果你想使用绝对导入,可以把模块 datacheck 里面的所有内容移动到包的 __init__.py 文件里,或者给它改个名字。

撰写回答