Python 相对导入与绝对导入

Python | Jul 21, 2016 | python

Python 相对导入与绝对导入,这两个概念是相对于包内导入而言的。包内导入即是包内的模块导入包内部的模块。

Python import 的搜索路径

1.在当前目录下搜索该模块

2.在环境变量 sys.path 中指定的路径列表中依次搜索

3.在 Python 安装路径的 lib 库中搜索

Python import 的步骤

python 所有加载的模块信息都存放在 sys.modules 结构中,当 import 一个模块时,会按如下步骤来进行

如果是 import A,检查 sys.modules 中是否已经有 A,如果有则不加载,如果没有则为 A 创建 module 对象,并加载 A

如果是 from A import B,先为 A 创建 module 对象,再解析A,从中寻找B并填充到 A 的 dict 中

相对导入与绝对导入

绝对导入的格式为 import A.B 或 from A import B,相对导入格式为 from . import B 或 from ..A import B,.代表当前模块,..代表上层模块,...代表上上层模块,依次类推。

相对导入可以避免硬编码带来的维护问题,例如我们改了某一顶层包的名,那么其子包所有的导入就都不能用了。但是 存在相对导入语句的模块,不能直接运行,否则会有异常:

ValueError: Attempted relative import in non-package

这是什么原因呢?我们需要先来了解下导入模块时的一些规则:

在没有明确指定包结构的情况下,Python 是根据 name 来决定一个模块在包中的结构的,如果是 main 则它本身是顶层模块,没有包结构,如果是A.B.C 结构,那么顶层模块是 A。基本上遵循这样的原则:

如果是绝对导入,一个模块只能导入自身的子模块或和它的顶层模块同级别的模块及其子模块

如果是相对导入,一个模块必须有包结构且只能导入它的顶层模块内部的模块

如果一个模块被直接运行,则它自己为顶层模块,不存在层次结构,所以找不到其他的相对路径。

Python2.x 缺省为相对路径导入,Python3.x 缺省为绝对路径导入。绝对导入可以避免导入子包覆盖掉标准库模块(由于名字相同,发生冲突)。如果在 Python2.x 中要默认使用绝对导入,可以在文件开头加入如下语句:

from future import absolute_import

from future import absolute_import

这句 import 并不是指将所有的导入视为绝对导入,而是指禁用 implicit relative import(隐式相对导入), 但并不会禁掉 explicit relative import(显示相对导入)。

那么到底什么是隐式相对导入,什么又是显示的相对导入呢?我们来看一个例子,假设有如下包结构:

thing

├── books

│ ├── adventure.py

│ ├── history.py

│ ├── horror.py

│ ├── __init__.py

│ └── lovestory.py

├── furniture

│ ├── armchair.py

│ ├── bench.py

│ ├── __init__.py

│ ├── screen.py

│ └── stool.py

└── __init__.py

那么如果在 stool 中引用 bench,则有如下几种方式:

import bench # 此为 implicit relative import

from . import bench # 此为 explicit relative import

from furniture import bench # 此为 absolute import

隐式相对就是没有告诉解释器相对于谁,但默认相对与当前模块;而显示相对则明确告诉解释器相对于谁来导入。以上导入方式的第三种,才是官方推荐的,第一种是官方强烈不推荐的,Python3 中已经被废弃,这种方式只能用于导入 path 中的模块。

相对与绝对仅针对包内导入而言

最后再次强调,相对导入与绝对导入仅针对于包内导入而言,要不然本文所讨论的内容就没有意义。所谓的包,就是包含 init.py 文件的目录,该文件在包导入时会被首先执行,该文件可以为空,也可以在其中加入任意合法的 Python 代码。

相对导入可以避免硬编码,对于包的维护是友好的。绝对导入可以避免与标准库命名的冲突,实际上也不推荐自定义模块与标准库命令相同。

前面提到含有相对导入的模块不能被直接运行,实际上含有绝对导入的模块也不能被直接运行,会出现 ImportError:

ImportError: No module named XXX

这与绝对导入时是一样的原因。要运行包中包含绝对导入和相对导入的模块,可以用 python -m A.B.C 告诉解释器模块的层次结构。

有人可能会问:假如有两个模块 a.py 和 b.py 放在同一个目录下,为什么能在 b.py 中 import a 呢?

这是因为这两个文件所在的目录不是一个包,那么每一个 python 文件都是一个独立的、可以直接被其他模块导入的模块,就像你导入标准库一样,它们不存在相对导入和绝对导入的问题。相对导入与绝对导入仅用于包内部。

python 相对导入_python 相对导入与绝对导入相关推荐

  1. python import 路径_python import 上级目录的导入

    python import 上级目录的导入,路径,上级,文件,目录,递归 python import 上级目录的导入 易采站长站,站长之家为您整理了python import 上级目录的导入的相关内容 ...

  2. python封装举例_Python+Pycharm—学习1—封装导入

    一.封装 目的: 写了一个复杂功能的实现,下次有相同的需求时可以直接导入这个包来使用.就可以达到复用的目的了.通俗的来讲就是打包.(以下用四则运算举例) 方案: 1.1.新建python工程,新建一个 ...

  3. python中re模块怎么导入_python如何导入re模块

    正则表达式是一个特殊的字符序列,能方便的检查一个字符串是否与某种模式匹配.re模块使得python拥有全部的正则表达式功能. 正则表达式导入方法import re 在python中默认采用的是贪婪模式 ...

  4. python模块导入_Python模块导入详解

    定义 模块:用来从逻辑上组织Python代码(变量.函数.类.逻辑)去实现一个功能.本质就是.py结尾的Python文件. 包:用来从逻辑上组织模块的(可以放一堆模块在目录下).本质就是一个目录(必须 ...

  5. python自建模块导入_Python模块的使用及自建模块的导入方法举例

    模块使用 模块: 模块式pyth1.on组织代码的基本方式 一个python脚本可以单独运行,也可以导入另一个脚本中运行,当脚本被导入运行时,我们将其称为模块(module) 所有的点p为文件都可以作 ...

  6. python模块导入_Python模块及其导入

    一.模块 1.模块的定义: 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少, 很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件 ...

  7. python绝对导入_Python中的绝对导入和相对导入

    如果你做过有多个文件的Python项目,那么你一定用过import语句. 即使是对于有多个项目的Python支持者来说,import也会让人困惑!你可能正阅读本文,因为希望更深入地了解Python中的 ...

  8. python random模块导入_Python学习笔记(二十)—模块的导入

    一.模块介绍 Python 提供了强大的模块支持,主要体现在Python 标准库中包含了大量的模块(称为标准模块),还有大量的第三方模块,开发者自己也可以开发自定义模块.通过这些强大的模块可以极大地提 ...

  9. python导入模块的语法结构_python学习第五讲,python基础语法之函数语法,与Import导入模块....

    python学习第五讲,python基础语法之函数语法,与Import导入模块. 一丶函数简介 函数,就是一个代码块,这个代码块是别人写好的.我们调用就可以. 函数也可以称为方法. 1.函数语法定义 ...

最新文章

  1. 【java】Maven工程引入各种jar包的功能
  2. 基于享元记忆的 Boost.Flyweight 示例
  3. autocad软件提供的哪些功能可以提高设计效率?_节省80%制图时间:AutoCAD如何有效“手脑”结合,释放创作潜能?...
  4. Android学习——数据存储
  5. C#趣味程序---爱因斯坦的台阶问题
  6. (3)分布式下的爬虫Scrapy应该如何做-递归爬取方式,数据输出方式以及数据库链接...
  7. 第十九章:李丽质入狱
  8. oracle ebs 采购订单 为员工分配职务,oracle—EBS-采购功能点操作手册
  9. 计算机网络重置点命令,重置网络命令
  10. 计算机组成原理英文词汇,“计算机组成原理”课专业词汇英汉对照.pdf
  11. 【信号处理】脉搏信号处理系统含Matlab源码
  12. sparkstream报错 Caused by: org.apache.spark.SparkException: This RDD lacks a SparkContext. It could ha
  13. 硬币组合问题python_Python,求钱币组合情况,用一分两分和五分的硬币攒的钱一元钱,的所有情况...
  14. OSChina 周一乱弹 —— 为单身狗准备的菜
  15. 360企业版服务器修改了,360企业版安装部署方法详细攻略
  16. 怎么打开ofd文件的三种方法
  17. 东山再起的男人一般都有这七个表现
  18. Java面试题总结2020
  19. c语言sizeof char,sizeof 你真的弄明白了吗?来看看这个例子
  20. 为什么要说“链上KYC”是Web3.0失败的前奏

热门文章

  1. excel实战应用案例100讲(四)-Excel玩转数据:从分析到可视化
  2. 数据挖掘实战项目-客户流失及客户行为偏好分析
  3. 少儿编程150讲轻松学Scratch(六)-少儿编程命名规则
  4. matlab13节点线路模型,13节点配电网的建模与仿真.doc
  5. WebCrack:网站后台弱口令批量检测工具
  6. HTML 页面自动刷新
  7. JS中深浅拷贝 函数封装代码
  8. css定位position
  9. 分享几道经典的javascript面试题
  10. 子元素的margin-top会影响父元素