开发Python模块时如何使用绝对导入?

3 投票
2 回答
3726 浏览
提问于 2025-04-18 23:44

我知道相对导入并不被推荐,比如在PEP8中提到:

在包内部使用相对导入是非常不推荐的。所有导入都应该使用绝对包路径。即使现在PEP 328在Python 2.5中已经完全实现,它的显式相对导入风格仍然不被鼓励;绝对导入更具可移植性,通常也更易读。

如果我正在开发一个包含多个模块的包呢?在开发过程中,绝对导入在没有安装或部署包的情况下是无法工作的。这是否意味着我必须定期安装或部署当前正在开发的模块来进行测试呢?

这里有一个Cld提供的例子。假设有一个Python项目/包:

myproject/
  package1/
     __init__.py
     somemodule.py
  package2/
     __init__.py
     somemodule.py
     somescript.py
main.py

main.py中,绝对导入工作得很好:

import package1
import package2.somescript
import package2.somemodule

但是,对于像包2中的somescript.py这样的模块,以下的绝对导入:

import package2.somemodule
import package1

会引发ImportError错误:

Traceback (most recent call last):
  File "package2/somescript.py", line 1, in <module>
    import package2.somemodule
ImportError: No module named package2.somemodule

2 个回答

1

一个常见的做法是使用 pip install -e /path_to_your_pkg/ 命令,这个命令会在Python的库目录中创建你包的一个符号链接,而不是像普通安装那样复制包。这样做的好处是:

  • 你可以在任何地方导入你的包
  • 你可以继续开发或更新你的包,安装的版本总是最新的

不过,有一个已知的问题是,如果你按照PEP 517的规范,把 setup.py 替换成 setup.cfgpyproject.toml,那么 pip install -e 就会失效。为了修复这个兼容性问题,你需要一个简单的 setup.py,如下所示(这个问题在2021年1月仍然存在):

import setuptools
setuptools.setup()
3

这要看你的“主”文件在哪里。

如果你有:

myproject/
  package1/
     __init__.py
     somemodule.py
  package2/
     __init__.py
     somemodule.py
     somescript.py
  main.py

somescript.py:

import package2.somemodule
import package1

main.py

import package1
import package2.somescript
import package2.somemodule

如果你执行:python package2/somescript.py,你会遇到一个错误。

Traceback (most recent call last):
  File "package2/somescript.py", line 1, in <module>
    import package2.somemodule
ImportError: No module named package2.somemodule

但是如果你执行 python main.py,就不会有问题。

撰写回答