文件查找与当前工作目录的切换
在执行python hello.py
时,大家有可能会看到终端上显示出错误:
$ python hello.py
python: can't open file 'hello.py': [Errno 2] No such file or directory.
这和Python解释器的文件查找机制有关。
大家还记得先前提到的“当前工作目录”的概念吗。不记得了可以跳回2.2节去看一眼:终端会在提示符里面显示当前的工作目录。
而当你键入python hello.py
时,Python解释器会在当前的工作目录里去找hello.py
并执行。
而如果你当前工作目录下没有hello.py
文件时,Python解释器就会报错了。
举个错误的例子:假设你有一个文件夹叫做C:\SICP
,并且你把我们下发的实验材料的压缩包解压在了这个文件夹中,也就是说你的实验材料都在C:\SICP\lab00
下。
但是你打开终端的时候,默认的当前工作目录可能是C:\User\Dell
(在你的电脑上可能是其它工作目录),而现在你知道hello.py
在C:\SICP\lab00\code
目录下,那么当你执行:
C:\User\Dell> python hello.py
就会出现问题。但如果你当前的工作目录是C:\SICP\lab00\code
,那么你执行:
C:\SICP\lab00\code> python hello.py
就不会有任何问题。那么接下来你就会问,该如何改变当前的工作目录呢?你可以通过cd
这个命令切换终端的当前工作目录!
cd
的全称是change directory。
一方面,你可以通过cd
后跟一个目录的“绝对路径”来把工作目录切换成“绝对路径”所表示的目录。
比如在上面的例子中,如果你当前的工作目录是C:\User\Dell
,那么你可以像下面这样切换当前的工作目录到C:\SICP\lab00\code
:
C:\User\Dell> cd C:\SICP\lab00\code
C:\SICP\lab00\code>
什么是绝对路径?像
C:\SICP\lab00\code
以盘符(C盘的盘符叫做C:
,D盘的盘符叫做D:
,以此类推)开头的路径,就叫做绝对路径。否则叫相对路径。在macOS和Linux中并不存在“盘符”的概念,在这些操作系统中,最底层的文件夹叫做“根目录”(
/
,也就是“root”),以/
开头的路径叫做绝对路径,如/home/user/sicp/lab00/code
。你可能会注意到,Windows上路径的目录之间使用
\
分割,而macOS和Linux则使用/
分割。
另一方面,你也可以通过cd
后跟一个目录的“相对路径”来把工作目录切换成“相对路径”所表示的目录。
比如,如果你当前的工作目录为C:\SICP\lab00
,并且这个目录下还有一个code
目录,那么你可以像这改变当前的工作目录:
C:\SICP\lab00> cd code
C:\SICP\lab00\code>
这里的code
就是相对路径。这个过程就很像你在资源管理器的lab00
目录下双击了code
目录,然后就进入了lab00\code
目录一样。
如果你的C:\SICP\lab00
下没有code
目录,那么终端上就会显示错误。你可能需要打开资源管理器看看是怎么回事。
接下来你可能会想知道如何回到上一级目录或者切换磁盘。下面是一些演示:
..
的含义为上一级目录。.
的含义为当前目录。可以使用cd a\b\c
这样的形式一口气进入多层目录(a\b\c
就是所谓的相对路径)。C:\SICP\lab00\code> cd .. # 进入上层目录 C:\SICP\lab00> cd .. # 再次进入上层目录 C:\SICP> cd lab00\code # 进入lab00目录下的code目录 C:\SICP\lab00\code> cd ..\.. # 进入上层目录的上层目录 C:\SICP> cd .\lab00 # 进入当前目录的lab00目录 C:\SICP\lab00> cd ..\lab00 # 进入上层目录的lab00目录 (即还是当前目录) C:\SICP\lab00>
- 在Windows上,如果当前目录的盘符与目标目录的盘符不同,你首先需要通过"{盘符}:"命令切换盘符。
C:\SICP\lab00> cd D:\NJU # 无效的切换 C:\SICP\lab00> D: # 有效的切换 D:\NJU>
- 一般来说,Windows的路径不区分大小写,macOS和Linux是否区分取决于你安装系统时的选择。
当前工作目录下的有哪些目录与文件?(可选)
你可以通过dir
命令(在Windows上)或ls
命令(在macOS和Linux上)显示当前目录下的文件。
例如,在Windows下:
C:\SICP\lab00\code>dir
驱动器 C 中的卷是 Windows
卷的序列号是 4C0F-CDB0
C:\SICP\lab00\code 的目录
2020/09/21 10:37 <DIR> .
2020/09/21 10:37 <DIR> ..
2020/09/21 15:03 19 hello.py
2020/09/19 17:48 480 lab00.py
2 个文件 499 字节
3 个目录 100,005,732,352 可用字节
在macOS和Linux下:
~\SICP\lab00\code$ ls
hello.py lab00.py
命令的格式(可选)
现在,大家应该已经执行过很多命令了。 接下来,我们带好奇的同学总结一下命令的通用格式是什么样的。
一般来说,命令的格式如下:
$ executable [-option [parameter]]... [positional-parameter]...
其中:
executable
是一个可执行文件,比如在命令python --version
中,executable就是python
——它正是我们在第一节配置Python环境中所下载的可执行文件。[-option [parameter]]...
的中括号表示“可选”,省略号表示零个或多个。 它们加起来的意思是,executable
后面可以跟零个或多个形如-option [parameter]
这样的东西,其中-option
代表一个选项,-option [parameter]
代表选项后面可以跟一个可选的parameter,这视具体的选项而定——有的选项需要parameter,有的就不需要。- [positional-parameter]...
代表零个或多个positional-parameter。 这种positional-parameter与-option parameter中parameter的区别是,它不会跟在选项后面。
下面举几个例子就容易理解了:
- 在
python --version
这个命令中,--version
就是一个形如-option
的选项——这个选项的意思是叫python
这个可执行程序打印它的版本号。 此外,--version
后面不需要跟parameter。 - 在
cd C:\SICP\lab00
这个命令中,cd
概念上也是一个可执行文件。而且它后面没有任何形如-option [parameter]
这样的东西。 但是有一个绝对路径C:\SICP\lab00
作为positional-parameter。这表示把当前的目录切换到C:\SICP\lab00
。 - 在
python lab00.py
这个命令中,没有任何形如-option [parameter]
这样的东西。但是有个positional-parameter——lab00.py
。 这个命令表示启动Python解释器去执行lab00.py
里的代码。 - 在
python -i lab00.py
这个命令中(将在4.3节出现),有一个-i选项。注意,这里的lab00.py
不是-i
的parameter,而是positional-parameter——因为-i选项后不需要parameter。 在多了一个-i
选项后,这个命令就比前面讲解的python lab00.py
多了些功能——除了要像python lab00.py
一样启动Python解释器去执行lab00.py
里的代码, 还要让Python解释器执行完毕后进入交互模式,而不是直接退出Python解释器。 - 在
python -m doctest lab00.py
这个命令中(将在4.3节出现),有一个-m
选项。在这里,doctest
确实是-m
的parameter。 回顾一下,-m doctest
是一个形如-option [parameter]的东西。另外,这里的lab00.py
依旧是positional-parameter。 在多了一个-m doctest
后,这个命令比起前面两个命令的含义又产生了变化——Python解释器要启动doctest模块去执行lab00.py
里的doctest。
此外,-option
一般有两种约定俗成的形式:
- 一种是像
--version
这样的由两个连字符加上一个单词的形式。这种形式长得很“长”,方便理解。 - 一种是像
-i
这样的由一个连字符加上字母(一般是某个单词的首字母)的形式。这种形式长得很“短”,方便输入。