当前工作目录到底是什么?

What exactly is current working directory?

我的书说:

Every program that runs on your computer has a current working directory, or cwd. Any filenames or paths that do not begin with the root folder are assumed to be under the current working directory

因为我在 OSX,我的根文件夹是 /。当我在 Python shell 中输入 os.getcwd() 时,我得到 /Users/apple/Documents。为什么我的 cwd 中有 Documents 文件夹?是说 Python 正在使用 Documents 文件夹吗?是否有以 /(根文件夹)开头的指向 Python 的路径?另外,每个程序都有不同的cwd吗?

这与 osx 特别无关,它更像是所有基于 unix 的系统共享的概念,我相信 Windows 也是如此。 os.getcwd() 相当于 bash pwd 命令 - 它只是 returns 您当前所在位置的完整路径。换句话说:

alex@suse:~> cd /
alex@suse:/> python
Python 2.7.12 (default, Jul 01 2016, 15:34:22) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.getcwd()
'/'

这取决于您从哪里开始 python shell/script。

Python 通常(除非您正在使用虚拟环境)可以从您的任何目录访问。您可以检查路径中的变量,Python 应该可用。因此,当您询问 Python 时获得的目录就是您开始 Python 的目录。在开始 Python 之前更改 shell 中的目录,你会看到你会的。

os.getcwd() 与 OSX 无关。它只是 return 源文件的 directory/location。如果我的源文件在我的桌面上,它会 return C:\Users\Dave\Desktop\ 或者假设源文件保存在外部存储设备上,它可以 return 类似 G:\Programs\ 的东西。对于基于 unix 的系统和 Windows 系统都是一样的。

您的 python 解释器位置取决于您启动它的方式,以及启动它后采取的后续操作,例如使用 os 模块导航您的文件系统。只需启动解释器就会将您置于 python 安装目录中(在不同的操作系统上不同)。另一方面,如果您从编辑或 运行 特定目录中的文件开始,您的位置将是您正在编辑的文件所在的文件夹。如果您需要 运行 某个目录中的解释器并且您正在使用 idle,例如,最简单的方法是通过以某种方式在那里创建一个 python 文件开始,当您编辑它时,您可以开始a shell with 运行 > Python Shell 已经在该目录中。如果您使用的是命令行解释器,请在 运行 执行 python/python3/py 命令之前导航至您要 运行 解释器所在的文件夹。如果您需要手动导航,您当然可以使用已经提到的以下内容:

import os
os.chdir('full_path_to_your_directory')

每个进程都有一个当前目录。当一个进程启动时,它只是从它的父进程那里继承当前目录;例如,它没有设置为包含您正在使用的程序的目录。运行ning.

如需更详细的解释,请继续阅读。

当磁盘变得足够大以至于您不想将所有文件都放在同一个地方时,操作系统供应商想出了一种在 目录 中构建文件的方法。因此,与其将所有内容保存在同一目录(或“文件夹”,因为现在初学者被教导这样称呼它),不如在其中创建新集合和其他新集合(除了在某些早期实现中目录不能包含其他目录!)

从根本上说,目录只是一种特殊类型的文件,其内容是其他文件的集合,其中还可以包含其他目录。

在原始操作系统上,故事到此结束。如果您想打印一个名为 term_paper.txt 的文件,该文件位于目录 spring_semester 中,而该文件又位于目录 2021 中,该文件位于目录 studies 中的目录 mine,你不得不说

print mine/studies/2021/spring_semester/term_paper.txt

(除了命令可能比 print 更神秘,目录分隔符可能是方括号和冒号之类的疯狂东西;

lpr [mine:studies:2021:spring_semester]term_paper.txt

但这对于本次展览并不重要),如果您想复制该文件,则必须将整个辣酱玉米饼馅拼写两次:

copy mine/studies/2021/spring_semester/term_paper.txt mine/studies/2021/spring_semester/term_paper.backup

然后出现了当前工作目录的概念。如果您可以说“从现在开始,除非我另有说明,否则我所说的所有文件都将位于该特定目录中”会怎么样?因此 cd 命令诞生了(除了在像 VMS 这样的旧系统上,它被称为更笨重的东西,比如 SET DEFAULT)。

cd mine/studies/2021/spring_semester
print term_paper.txt
copy term_paper.txt term_paper.backup

仅此而已。当您 cd(或 Python、os.chdir())时,您更改了当前的工作目录。它会一直保留到您注销(或以其他方式退出此进程),或者直到您 cd 到另一个工作目录,或者切换到另一个进程或 window 您所在的位置 运行具有 自己的当前工作目录的单独命令。就像您可以在不同目录中打开多个 windows 文件浏览器(Explorer 或 Finder 或 Nautilus 或其他名称)一样,您可以打开多个终端,每个 运行 一个 shell 有自己独立的当前工作目录。

因此,当您在终端中键入 pwd(或 cwd 或您的命令语言中调用的任何命令)时,结果将在很大程度上取决于您在 window 或之前的流程,可能取决于您如何创建 window 或流程。在许多类 Unix 系统上,当您使用关联的 shell 进程创建新终端 window 时,它最初是在您的主目录中打开的(/home/you 在许多 Unix 系统上,/Users/you 在 Mac 上,或多或少类似于最近 Windows 上的 C:\Users\you),尽管您的终端可能可以配置为在其他地方打开(通常是 DesktopDocuments 在某些表面上“现代”和“友好”系统上的主目录中。

许多初学者对 运行 程序时发生的情况有一个模糊且不完整的心理模型。许多人会不停地 cd 进入任何包含他们的脚本或程序的目录,当您告诉他们您不必这样做时,他们真的会感到害怕和困惑。如果 frobozz/home/you/bin 中,那么您不必

cd /home/you/bin
./frobozz

因为您可以简单地 运行 直接使用

/home/you/bin/frobozz

同样,如果 ls/bin 中,您绝对不会

cd /bin
./ls

只是为了获取目录列表。

此外,像 ls(或 Windows、dir)示例应该很容易说服您,您 运行 会在 [=118= 中查找任何程序]您的 当前文件目录。不是保存程序或脚本的目录。因为如果是这种情况,ls 只能生成它所在目录的列表 (/bin)——目录列表没有什么特别之处程序,或复制程序,或文字处理程序;它们都按照设计在当前工作目录中查找(不过,一些 GUI 程序将 start 与例如您的 Documents 目录作为它们的当前工作目录,通过设计,在至少如果你不告诉他们的话)。

许多初学者编写的脚本要求输入和输出文件位于特定用户主目录中的特定目录中,但这是糟糕的设计;除非另有说明,否则编写良好的程序将简单地在当前工作目录中查找其输入文件,并将输出写入当前目录(或者如果它包含多个文件,则可能在当前目录中为其输出创建一个新目录)。

Python,那么,与任何其他程序没有什么不同。如果您当前的工作目录是 /Users/you/Documents 而您 运行 python 那么该目录就是您的 Python 脚本或解释器中的 os.getcwd() 将生成的目录(除非您单独 os.chdir() 在 运行 时间到不同的目录;但同样,这可能是不必要的,并且通常表明脚本是由初学者编写的)。如果您的 Python 脚本接受文件名参数,它可能应该简单地让操作系统 open 无论用户输入什么,这意味着相对文件名是相对于调用用户当前工作目录的。

python /home/you/bin/script.py file.txt

应该简单地 open(sys.argv[1]) 并且如果 file.txt 在当前目录中不存在则失败并出现错误。让我们再说一遍;它不会在 /home/you/bin 中查找 file.txt —— 当然除非那也是你的当前工作目录,调用用户,在这种情况下你当然可以简单地写

python script.py file.txt

在相关说明中,许多初学者不必要地尝试类似

with open(os.path.join(os.getcwd(), "input.txt")) as data:
    ...

不必要地调用 os.getcwd()。为什么是不必要的?如果您一直在关注,那么您已经知道答案了:无论如何,操作系统都会在当前工作目录中查找相对文件名(如此处 input.txt)。所以你只需要

with open("input.txt") as data:
    ...

最后一点。在类 Unix 系统上,所有文件最终都在根目录 / 中,该目录包含许多其他目录(通常不允许普通用户在那里写任何东西,有权限的系统管理员通常不会这样做'想要)。通过跟踪从根目录到当前目录的路径,可以将每个相对文件名转换为绝对文件名。所以如果我们要访问的文件在/home/you/Documents/file.txt里面就说明home在根目录下,里面有you,里面有Documents,里面有[=55] =].如果您当前的工作目录是 /home,您可以通过相对路径 you/Documents/file.txt 引用同一个文件;如果您的当前目录是 /home/you,则它的相对路径将是 Documents/file.txt(如果您的当前目录是 /home/you/Music,您可以说 ../Documents/file.txt,但我们不要拿这个例子现在更进一步)。

Windows排列略有不同,许多驱动器具有单字母标识符,每个驱动器都有自己的根目录;所以 C: 驱动器的根目录是 C:\ 而 D: 驱动器的根目录是 D:\ 等等(目录分隔符是反斜杠而不是斜杠,尽管你可以使用斜杠代替几乎无处不在,这通常是保持理智的好主意)。