什么是Python中的绝对导入?

25 投票
2 回答
50934 浏览
提问于 2025-04-18 00:06

我刚开始学习Python,正在做一个小项目。我想从一开始就遵循编码标准。请问应该怎么正确使用import语句呢?现在我在用Python 2.7。如果我换到3.x版本,会不会在绝对导入方面遇到什么问题?绝对导入和相对导入有什么区别呢?

2 个回答

3

导入语句通常应该写在单独的行上:

对的写法:import os import sys

错的写法:import sys, os

不过可以这样写:

from subprocess import Popen, PIPE

导入语句总是放在文件的最上面,紧接着模块的注释和文档字符串,然后是模块的全局变量和常量。

导入语句应该按以下顺序分组:

  • 标准库的导入。
  • 相关的第三方库导入。
  • 本地应用或库特定的导入。
  • 每组导入之间应该留一行空行。

根据Pep8的规定:推荐使用绝对导入,因为它们通常更易读,并且在导入系统配置错误时(比如包内的某个目录意外出现在sys.path中),表现得更好(或者至少能给出更好的错误信息):

import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example

不过,显式的相对导入也是绝对导入的一个可接受的替代方案,特别是在处理复杂的包结构时,使用绝对导入会显得过于冗长:

from . import sibling
from .sibling import example

标准库的代码应该避免复杂的包结构,并始终使用绝对导入。

隐式相对导入应该永远避免,并且在Python 3中已经被移除。

当从包含类的模块中导入一个类时,通常可以这样写:

from myclass import MyClass
from foo.bar.yourclass import YourClass

如果这样写会导致本地名称冲突,那么就要明确地写出:

import myclass
import foo.bar.yourclass

并使用“myclass.MyClass”和“foo.bar.yourclass.YourClass”。

通配符导入(from <module> import *)应该避免使用,因为它会让人不清楚命名空间中有哪些名称,这会让读者和许多自动化工具感到困惑。通配符导入有一个可以辩护的用例,就是将内部接口重新发布为公共API的一部分(例如,用可选加速模块中的定义覆盖纯Python实现的接口,而具体会覆盖哪些定义在事先并不知道)。

https://www.python.org/dev/peps/pep-0008/#imports

40

这里提到的 absolute(绝对)和 relative(相对)之间的区别,跟我们谈论绝对路径和相对路径,甚至是网址的方式很相似。

绝对 {导入、路径、网址} 会告诉你确切的获取目标的方法,通常是通过指定每一个部分来实现:

import os, sys
from datetime import datetime
from my_package.module import some_function

相对 {导入、路径、网址} 就如它们的名字所示:它们是相对于当前的位置的。也就是说,如果目录结构发生变化或者文件移动了,这些相对路径可能会失效(因为它们不再指向同样的东西)。

from .module_in_same_dir import some_function
from ..module_in_parent_dir import other_function

因此,对于需要共享的代码,通常更推荐使用绝对导入。


有人在评论中让我举个例子,说明 from __future__ import absolute_import 是怎么和这个概念相关的,以及它应该怎么使用。在尝试举例的时候,我发现自己也没法很好地解释它的行为,所以我问了一个新问题这个回答提供了一个代码示例,展示了 from __future__ import absolute_import 的正确用法,它实际上解决了一个模糊性的问题。

被接受的回答更详细地解释了为什么它会这样工作,包括对 Python 2.5 更新日志中令人困惑的措辞的讨论。简单来说,这个指令的作用范围(以及绝对导入和相对导入在 Python 中的区别)是非常非常狭窄的。如果你发现自己需要这些区别才能让代码正常工作,可能最好还是重命名你的本地模块,如果有可能的话。

撰写回答