python绝对导入与相对导入(包内导入)(在创建自己的包、模块或系统工程时会用到的知识)

Part 1

我们先上案例,再分析原因。

若在pycharm新建工程,再创立几个文件,文件结构如下图

在这里插入图片描述
也就是说,我们在工程下有文件test.py和文件夹p,在p下分别有run.pytool.py两个文件

一开始,py文件中都为空,现在一步一步来

先在test文件中写入import p.run,然后运行test文件,发现程序正常运行;

我们再在run文件中写入import tool,运行run,发现依然正常。

我们再回到test文件,运行,结果如下:

ModuleNotFoundError: No module named 'tool'

系统无法找到tool模块,这是为什么?

因为我们平时运行import时,是没有指明路径的,此时系统会从sys.path中寻找路径,来依次查看每一个路径中是否有我们需要的模块,我们修改test文件如下,并运行

# import p.run
import sys
print(sys.path)

结果为:

['D:\\code\\pythonProjectTest', 'D:\\code\\pythonProjectTest', 'D:\\Python\\Python39\\Lib\\site-packages', 'D:\\Python\\Python39\\python39.zip', 'D:\\Python\\Python39\\DLLs', 'D:\\Python\\Python39\\lib', 'D:\\Python\\Python39', 'D:\\code\\pythonProjectTest\\venv', 'D:\\code\\pythonProjectTest\\venv\\lib\\site-packages']

我们再来到`run模块,执行如下代码:

# import tool
import sys
print(sys.path)

有结果:

['D:\\code\\pythonProjectTest\\p', 'D:\\code\\pythonProjectTest', 'D:\\Python\\Python39\\Lib\\site-packages', 'D:\\Python\\Python39\\python39.zip', 'D:\\Python\\Python39\\DLLs', 'D:\\Python\\Python39\\lib', 'D:\\Python\\Python39', 'D:\\code\\pythonProjectTest\\venv', 'D:\\code\\pythonProjectTest\\venv\\lib\\site-packages']

系统检索sys.path的机制和windows中的PATH是类似的,因此不再解释

我们只看sys.path的前2项,其中第一项是当前py文件所属文件夹,第二项是工程文件夹。而一旦执行了某个py文件,sys.path就已经确定了

因此原因就出来了,我们之前执行test文件时,生成的sys.path不会含有'D:\\code\\pythonProjectTest\\p'路径,自然就找不到模块tool

Part 2

我们依然一边运行,一边分析

之前无法在run中导入tool,现在我们把run中代码改为from . import tool,在回到test执行代码,会发现程序正常运行。

原因:我们采用了相对路径而不是绝对路径,.代表所属上一级目录。此外,..代表上上级目录

这里需要额外说明的是,不能像在命令行中把...完全理解为针对目录的操作,因为在python中,上一级和上上级是针对模块名称进行操作的。也许说得有点抽象,我们上代码:在testrun中,分别在第二行加入语句print(__name__),然后在test中执行,有:

p.run
__main__

其中run中的语句先打印,这一点大家应该明白。

也就是说,每个模块都有一个__name__属性,若某模块直接以脚本的方式被执行,那么模块名称就是__main__,而若使用模块的方式被加载,模块名就会对应地改变

之后,run模块的模块名称就是p.runp就是它的顶级名称(类似目录),也就是在run中能够访问到的最高级。

比如我们在test同级处新建文件test2,改run中代码为from .. import test2,之后来到test并执行,有结果

ImportError: attempted relative import beyond top-level package

即超越了顶级包的位置,不能访问。同理,在脚本文件中也不能使用.的方式来访问属于同一层级的其他模块,因为包名__main__中并没有层级结构

以上适用于py3,py2有所不同,但使用越来越少,不再说明了。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值