什么是Python中的绝对导入?
我刚开始学习Python,正在做一个小项目。我想从一开始就遵循编码标准。请问应该怎么正确使用import
语句呢?现在我在用Python 2.7。如果我换到3.x版本,会不会在绝对导入方面遇到什么问题?绝对导入和相对导入有什么区别呢?
2 个回答
导入语句通常应该写在单独的行上:
对的写法: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实现的接口,而具体会覆盖哪些定义在事先并不知道)。
这里提到的 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 中的区别)是非常非常狭窄的。如果你发现自己需要这些区别才能让代码正常工作,可能最好还是重命名你的本地模块,如果有可能的话。