python:import
python的引用有两种方式:绝对引用、相对引用,从形式上看,二者的区别就在于模块前面是否有.
或..
。
后续解释均以下面结构为例:
xiaomeng
├─sub01
│ ├─a.py
│ ├─b.py
│
└─sub02
└─sub01.py
- 绝对引用
当使用绝对引用的方式时,python会从一系列既定的路径列表中依次搜索路径直到找到相应模块或者报错“模块xx不存在”。而这个路径列表就是sys.path
。
当在a.py中使用print(sys.path)
:
['E:\\download_apps\\PyCharm 2022.1.3\\workplace\\xiaomeng\\root\\sub01', 'E:\\download_apps\\PyCharm 2022.1.3\\workplace\\xiaomeng',
'E:\\download_apps\\PyCharm 2022.1.3\\plugins\\python\\helpers\\pycharm_display',
'C:\\Users\\User_name\\.conda\\envs\\PY110\\python37.zip', ...]
这里的内容为:[运行文件所在目录,项目根路径,项目内置库目录,...,手动append目录]
-
a import b
运行a.py文件时,python就会从a的sys.path中依次寻找包含了b的路径,如果找不到就提示“b模块不存在”
-
a import demo01
当使用a引用demo01时,
由于a的sys.path不包含root路径,所以就会找不到demo01模块:
当然我们可以从项目根路径出发,通过import root.sub01.demo0
来访问到,但是现在我就想从root出发通过import sub01.demo01
来访问demo01。所采取的方法应该是讲这个root
路径添加到sys.path
中,
具体为
结果正确:
- 相对引用
当使用绝对引用的方式时,python会以主引用文件的__name__为起点查找被引用文件。
这里会有两种错误:ImportError: attempted relative import with no known parent package
、ValueError: attempted relative import beyond top-level package
。
-
入口文件相对引入
对于入口文件(初始运行的文件)而言,它的__name__一定是__main__
,所以,如果入口文件使用相对引入,那么查找路径就相当于__main__.xx
,而项目中本就没有__main__
这个文件存在,所以就会报错“非法父目录”,即ImportError: attempted relative import with no known parent package
;
所以,入口文件不要使用相对引用方式。
-
非入口文件相对引入
对于非入口文件,它的__name__
取决于被引用的方式:
这里a的__name__就是在demo01中引用的那样,而此时在a中的相对引入就从root/sub01
出发,自然能找得到b
- 报错:
ValueError: attempted relative import beyond top-level package
在第二小节中已经提到过这个错误。顾名思义,这个错误发生在相对引入的路径超出了最高级路径导致的,只要明白这个“top-level”,一切都好解决了。
实际上,这个“top-level”指的是__name__的"top-level",如:
这里a的__name__为sub01.a
,以sub01
为起点开始查找,而from ..b
对应的路径则是sub01..b
,这里sub01
已经是__name__中的"top-level",再向上查找一级就会报错“超出top-level”。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)