Python中的导入
目录
Python import 的搜索路径
- 当前目录
- 环境变量 PYTHONPATH 中指定的路径列表中依次搜索
- 在 Python 安装路径的 lib 库中搜索
绝对导入
绝对导入有以下几种格式:
|
|
除此之外还有一种 from foo import *
的形式,但是不推荐使用。原因是这样会打乱命名空间。模块导入的函数可能会与自定义的函数或变量重名,造成未知的 bug。
相对导入
PEP328 介绍了引入相对导入的原因,以及选择了哪种语法。
具体来说,使用句点来决定如何相对导入其他包或模块,多个文件层级使用多个句点。不过 PEP328 建议相对导入的层级不要超过两层。
|
|
需要注意的是,存在相对导入的语句的模块,不能直接运行,否则会有异常。
|
|
原因如下:
在没有明确指定包结构的情况下,Python 是根据
__name__
来决定一个模块在包中的结构的,如果是__main__
则它本身是顶层模块,没有包结构;如果是A.B.C
结构,那么顶层模块是 A。基本上遵循这样的原则:
- 如果是绝对导入,一个模块只能导入自身的子模块或和它的顶层模块同级别的模块及其子模块;
- 如果是相对导入,一个模块必须有包结构且只能导入它的顶层模块内部的模块;
如果一个模块被直接运行,则它自己为顶层模块,不存在层次结构,所以找不到其他的相对路径。
如果想要在直接运行的模块中使用相对导入,那么可以通过将路径添加到 Python 检索路径的方式。
|
|
注意,相对导入与绝对导入仅用于包内部。如果是同一个目录下的两个文件,且目录不是一个包,那么每一个 python 文件都是一个独立的可以直接被其他模块导入的模块,就像导入标准库一样,它们不存在相对导入和绝对导入的问题。
导入注意事项
循环导入
如果创建了两个模块,二者互相导入对方,就会出现循环导入。运行任何一个模块,都会引发 AttributeError
。
在 《Flask Web 开发:基于 Python 的 Web 应用开发实战》中,第七章的大型结构有一个 hack 循环导入的方法——将导入代码放到模块的末尾。
但是,这与“所有的导入语句都应该位于模块的顶部”的约定相悖,因此并不是一个好的方案。在解决循环导入的问题时,首先考虑的方案应该是重构代码。