如何确定:

当前目录(运行Python脚本时我在shell中的位置),以及我正在执行的Python文件在哪里?


当前回答

Python 3.4中引入的路径库模块(PEP428-路径库模块-面向对象的文件系统路径)使路径相关的体验更好。

pwd

/home/skovorodkin/stack

tree

.
└── scripts
    ├── 1.py
    └── 2.py

要获取当前工作目录,请使用Path.cwd():

from pathlib import Path

print(Path.cwd())  # /home/skovorodkin/stack

要获取脚本文件的绝对路径,请使用path.resolve()方法:

print(Path(__file__).resolve())  # /home/skovorodkin/stack/scripts/1.py

要获取脚本所在目录的路径,请访问.parent(建议在.parent之前调用.resolve()):

print(Path(__file__).resolve().parent)  # /home/skovorodkin/stack/scripts

记住__file__在某些情况下是不可靠的:如何在Python中获取当前执行文件的路径?。


请注意,Path.cwd()、Path.resolve()和其他Path方法返回路径对象(在我的例子中是PosixPath),而不是字符串。在Python 3.4和3.5中,这造成了一些麻烦,因为open内置函数只能处理字符串或字节对象,并且不支持Path对象,因此您必须将Path对象转换为字符串或使用Path.open()方法,但后一个选项要求您更改旧代码:

文件脚本/2.py

from pathlib import Path

p = Path(__file__).resolve()

with p.open() as f: pass
with open(str(p)) as f: pass
with open(p) as f: pass

print('OK')

输出

python3.5 scripts/2.py

Traceback (most recent call last):
  File "scripts/2.py", line 11, in <module>
    with open(p) as f:
TypeError: invalid file: PosixPath('/home/skovorodkin/stack/scripts/2.py')

如您所见,open(p)不适用于Python 3.5。

PEP 519-添加Python 3.6中实现的文件系统路径协议,将PathLike对象的支持添加到开放函数,因此现在可以直接将path对象传递到开放函数:

python3.6 scripts/2.py

OK

其他回答

我认为找到当前执行上下文名称的最简洁方法是:

current_folder_path, current_folder_name = os.path.split(os.getcwd())

如果您试图查找当前所在文件的当前目录:

操作系统不可知的方式:

dirname, filename = os.path.split(os.path.abspath(__file__))

如果要搜索当前执行的脚本的位置,可以使用sys.argv[0]获取完整路径。

要获取当前目录的完整路径,请执行以下操作:

os.path.realpath('.')

对于问题1,使用os.getcwd()#获取工作目录和os.chdir(r'D:\SSteam\stamapps\common')#设置工作目录


我建议对问题2使用sys.argv[0],因为sys.argv是不可变的,因此始终返回当前文件(模块对象路径),不受os.chdir()的影响。也可以这样做:

import os
this_py_file = os.path.realpath(__file__)

# vvv Below comes your code vvv #

但当PyInstaller编译时,该代码段和sys.argv[0]将无法工作或工作异常,因为魔法财产没有在__main__level中设置,而sys.argv[0]是调用可执行文件的方式(这意味着它会受到工作目录的影响)。