Python编程 | 系统编程 | 脚本运行上下文 | 当前工作路径
当前工作路径(CWD)在脚本的执行中是一个重要的概念。除非指定了绝对路径, 否则当脚本处理文件时将始终默认它们存在于CWD**。如前所述,脚本可以使用os.getcwd
获取明确的CWD路径,使用os.chdir
可以改变它的CWD。
谨记,没有完整目录路径的文件名将被映射到CWD路径,和你的PYTHONPATH设置无关。从技术上讲,一个脚本总是启动于CWD,而非它所在的目录。反之,import
永远首先搜索文件所在的目录,而非CWD(除非该脚本刚好在CWD目录)。
CWD、文件和import
路径
当你输入一个shell命令行,比如python dir1/dir2/file.py
来运行该脚本时,CWD是你键入该命令时所处的路径,而非dir1/dir2。另一方面,Python自动将脚本所处目录添加到模块搜索路径的最前,因而无论在哪儿运行,file.py总是可以导入*dir1/dir2/*中的其他文件。
我们编写一个简单的脚本,打印出它的CWD和模块搜索路径来说明:
alone@alone-Vostro-14-5401:/media/alone/Coding/Python/Python项目/pp4e/system$ cat where_am_i.py
import os
import sys
from icecream import ic
ic(os.getcwd())
ic(sys.path[:6])
input()
alone@alone-Vostro-14-5401:/media/alone/Coding/Python/Python项目/pp4e/system$ cd ..
alone@alone-Vostro-14-5401:/media/alone/Coding/Python/Python项目/pp4e$ set PYTHONPATH=/media/alone/Coding/
alone@alone-Vostro-14-5401:/media/alone/Coding/Python/Python项目/pp4e$ python system/where_am_i.py
ic| os.getcwd(): '/media/alone/Coding/Python/Python项目/pp4e'
ic| sys.path[:6]: ['/media/alone/Coding/Python/Python项目/pp4e/system',
'/home/alone/anaconda3/lib/python37.zip',
'/home/alone/anaconda3/lib/python3.7',
'/home/alone/anaconda3/lib/python3.7/lib-dynload',
'/home/alone/anaconda3/lib/python3.7/site-packages']
alone@alone-Vostro-14-5401:/media/alone/Coding/Python/Python项目/pp4e$ set PYTHONPATH=/home/alone
alone@alone-Vostro-14-5401:/media/alone/Coding/Python/Python项目/pp4e$ python system/where_am_i.py
ic| os.getcwd(): '/media/alone/Coding/Python/Python项目/pp4e'
ic| sys.path[:6]: ['/media/alone/Coding/Python/Python项目/pp4e/system',
'/home/alone/anaconda3/lib/python37.zip',
'/home/alone/anaconda3/lib/python3.7',
'/home/alone/anaconda3/lib/python3.7/lib-dynload',
'/home/alone/anaconda3/lib/python3.7/site-packages']
这里,有两个陷阱我们需要避免:
- 如果不确定脚本的执行路径,最好使用完整的目录路径限定的文件名
- 命令行脚本不能总是依赖于CWD来导入不在它所处目录的文件,而应使用PYTHONPATH设置和包导入路径来访问其他目录中的模块
CWD和命令行
alone@alone-Vostro-14-5401:/media/alone/Coding/Python/Python项目/pp4e$ python ../../clean.py # process CWD
alone@alone-Vostro-14-5401:/media/alone/Coding/Python/Python项目/pp4e$ python ../../find.py *.py /home/alone/ # process named dir