【Python常见问题】【路径】路径总是有问题?深度剖析

一、什么是“路径”?

  • 路径,指的是Python在“找模块”时,到哪里去找。
  • 这些路径都存在一个叫sys.path的列表里。你可以在Python里打印出来看看
  import sys
  print(sys.path)

 二、Python找模块的顺序

  1. 当前脚本所在目录(你运行的那个.py文件的目录)
  2. 环境变量PYTHONPATH里设置的目录
  3. 标准库目录(比如你装Python时自带的库)
  4. site-packages(你用pip装的第三方库)

a.当前脚本所在目录

指的是你运行的那个.py文件所在的目录(不是被import的文件)

例如:

  • 在/home/user/project/目录下运行python src/main.py,那么“当前目录”就是/home/user/project/src/。
  • 在/home/user/project/目录下运行python -m src.main,那么“当前目录”就是/home/user/project/。
  • 这个目录会被自动加到sys.path的第一个位置。

b.环境变量PYTHONPATH

可以通过设置环境变量PYTHONPATH,让Python在import模块时,额外去你指定的目录里找。

例如:

  • Windows下:set PYTHONPATH=E:\my_libs
  • Linux/macOS下:export PYTHONPATH=/home/user/my_libs

这样你就可以importmy_libs目录下的模块了。

PYTHONPATH里的目录会被加到sys.path的前面(在标准库之前)。

c.标准库目录

Python自带的库,比如os、sys、json等。

这些库一般在你安装Python的目录下,比如C:\Python39\Lib或者/usr/lib/python3.9/。

这些目录在sys.path的后面。

d.site-packages

这是你用pip install安装的第三方库的存放目录。

一般在C:\Python39\Lib\site-packages或者/usr/local/lib/python3.9/site-packages/。

也在sys.path的后面,和标准库目录一起。

e.sys.path的顺序(举例)

假设你在E:\project目录下运行:

set PYTHONPATH=E:\my_libs
python src/main.py

此时sys.path大致如下(顺序很重要):

  1. E:\project\src(当前脚本目录)
  2. E:\my_libs(PYTHONPATH)
  3. C:\Python39\Lib(标准库)
  4. C:\Python39\Lib\site-packages(第三方库)

f.查找流程

当你写import xxx时,Python会按照sys.path的顺序,依次在每个目录下找有没有叫xxx.py或xxx包的文件夹,找到就用,找不到就继续下一个目录,直到找完所有目录。如果都找不到,就报ModuleNotFoundError。

三、项目中的单个文件的路径

你运行的那个.py文件所在的目录会被自动加到sys.path的第一个位置。

比如,当我把test.py放置在images下

此时的sys.path就会自动把test.py的父目录加到sys.path的第一个位置,如下图

当我把test.py放置在src下

此时的sys.path就会自动把test.py的父目录即src加到sys.path的第一个位置,如下图

四、运行路径与导入路径

当你在项目根目录下直接运行:python src/main.py

而在main.py中有类似于:from src.xxx import xxx 或者 from .xxx import xxx 就会出现“没有src模块”或“attempted relative import with no known parent package”等问题

如果你的项目结果如下:

xxx/
  ├── src/
  │    └── main.py
  └── 其他文件...

此时sys.path的第一个元素是xxx/src,而不是xxx

当在main.py中写   from src.datasets import dataset 时,python会去 src/src/datasets 下找,找不到就会报错

五、推荐做法

1.用 -m 参数

python -m src.main

解释 src.main 和 src/main 的区别
src.main 
  • 这是包名.模块名的写法。
  • src是包,main是src包下的main.py模块。
  • Python会自动去src目录下找main.py,并把src当作包来处理。
  • 这样包内的相对导入、绝对导入都能正常工作。
src/main(斜杠分隔)
  • 这是文件路径的写法,操作系统用来定位文件。
  • 不能用在python -m后面。
  • 如果你写python -m src/main,Python会报错,因为它只认包名和模块名的点号分隔方式。

2.设置PYTHONPATH

在根目录下运行:

set PYTHONPATH=.
python src/main.py

这样,(根目录)会被加到sys.path前面,也能找到src包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值