os.getcwd() 和 os.path.dirname(__file__) 之间的差异



在以前的项目中,我使用了以下两行的第一个版本。现在我找到了getcwd(),我认为这将是更短的选择。

print(os.path.dirname(__file__))  # D:/Personal_Software/my_project
print(os.getcwd())  # D:Personal_Softwaremy_project

我已经读过这篇文章,但我好奇的是"/"与"\"的使用。如果相关,我正在使用Windows 10。

  • __file__是提供给Python的文件名,与提供的文件完全相同。
  • os.path.dirname(__file__)通常是脚本所在的目录。(但并非总是如此,如下所示。
  • os.path.dirname(os.path.realpath(__file__))是脚本所在的目录。
  • os.getcwd()是当前目录。

当前目录与脚本所在的位置无关。它是用于解析相对路径的每个进程路径。

/tmp/ikegami/a.py

#!/usr/bin/python3
import os
print(__file__)
print(os.path.dirname(__file__))
print(os.path.dirname(os.path.realpath(__file__)))
print(os.getcwd())
[~]$ bin/a                # A symlink to /tmp/ikegami/a.py
bin/a                     # The path provided to python3.
bin                       # NOT the directory in which the script is located.
/tmp/ikegami              # The directory in which the script is located.
/home/ikegami             # The current directory (~ = /home/ikegami)
[~]$ /tmp/ikegami/a.py
/tmp/ikegami/a.py         # The path provided to python3.
/tmp/ikegami              # The parent of the path provided to python3.
/tmp/ikegami              # The directory in which the script is located.
/home/ikegami             # The current directory (~ = /home/ikegami)
[~]$ cd /tmp/ikegami
[/tmp/ikegami]$ ./a.py
./a.py                    # The path provided to python3.
.                         # The parent of the path provided to python3.
/tmp/ikegami              # The directory in which the script is located.
/tmp/ikegami              # The current directory

(这些测试是在Linux机器上运行的,因为我没有在这台Windows机器上安装python。你会在Windows上得到类似的结果。


我好奇的是"/"与"\"的使用。

Windows 始终接受/作为目录分隔符。[1][2],在此之前的DOS也是如此。[3]这些是等效的。是规范分隔符(为保持一致性而首选的分隔符),但/同样有效。

您的程序似乎是使用python3 D:/Personal_Software/my_project/file.py启动的。__file__包含提供给 Python 的确切路径,dirname(__file__)只是删除了最后一位。

另一方面,os.getcwd()从操作系统接收当前目录,操作系统可能返回当前目录的规范形式。


  1. 您甚至可以将//用于UNC路径(//server/share)和类似路径(//?/...//./...等)。

  2. 与已经提出的声明相反,系统调用(即 Win32 API)就是这种情况,资源管理器中就是这种情况("我的电脑"、"文件资源管理器"、"另存为"对话框等),Power Shell 就是这种情况(例如dir "c:/bin"c:/bin/myprog),在 Windows 控制台中就是这种情况(例如c:/bin/myprog)。

    警告:一些特定的 Windows 控制台命令(例如dir) 要求带有/的路径用引号引起来(例如dir "c:/"),因为/向他们发出期权开始的信号。

  3. 好吧,因为目录是在DOS 2.0中引入的。

这是有区别的,尽管您无法从单个脚本中分辨出来。

__file__是加载的模块或脚本的完整文件名,因此使用os.path.dirname(__file__)获取它的父目录会获得脚本所在的目录。

注意:在Linux(和类似的操作系统)上,这样的文件名可以是指向可能位于其他地方的实际文件的符号链接。如果需要,您可以使用os.path.realpath()通过任何此类链接进行解析,尽管您通常可以等效地使用符号链接。在 Windows 上,这些不太常见,但同样,您可以通过realpath()解析符号链接。

os.getcwd()获取当前工作目录。如果从脚本所在的目录(这很常见)启动脚本,则工作目录将与来自os.path.dirname(__file__)的调用的结果相同。

但是,如果您从另一个目录启动脚本(即python d:somepathscript.py),或者如果您在脚本期间更改了工作目录(例如,使用os.chdir()),则当前工作目录已更改,但脚本文件名的目录部分没有更改。

因此,这取决于您需要什么:

  • 需要脚本文件所在的目录?使用os.path.dirname(__file__)
  • 需要脚本当前运行的目录?请使用os.getcwd()

您会在某些结果中看到/,在其他结果中看到。可悲的是,MS Windows使用来分隔路径的各个部分(例如C:Program FilesApp),而几乎所有其他操作系统都使用/(例如/home/user/script.py)

Python通常会自动转换这些路径,因此您也可以在Windows上使用Python中的C:/Program Files/App路径,但是安全并使用os.path.sep往往是一个好主意。

注意:如果你使用的是Python 3,你最好只使用pathlibPath而不是os.path。它会自动解析符号链接(尽管如果您愿意,您仍然可以解析为链接),并且还具有其他不错的便利性。

最新更新