一、缘起
在Python代码中,我们往往需要获取当前目录和脚本所在目录。获取这两个目录的操作确实也比较简单(需要先引入内置模块os)。
获取当前目录的语句:
currpath = os.getcwd()
获取脚本所在目录的语句:
scriptpath = os.path.split(os.path.abspath(__file__))[0]
这个语句为什么要这么写,可以参照本号之前的一篇文章:
《获取当前Python脚本的绝对路径的正确方法》
https://mp.weixin.qq.com/s/k3f9dUmL5kgSbsQTSNQfjA
现在的问题来了,我们为什么需要这两个目录呢?让我们通过一个读取文本文件并显示其内容的小任务开始,来说明这个目录的重要性。
二、环境
Win7中文旗舰版64位 + Python 3.64 64位
三、引入
准备一个ANSI编码的文本文件test.txt,放入如下目录:
C:\Users\dyjxx\Desktop\scriptpath
该文件的内容如下:
==============内容开始,不包含本行==============
飞雪连天射白鹿,
笑书神侠倚碧鸳。
==============内容结束,不包含本行==============
现在我们写一个Python脚本test0.py来读取该文本文件的内容。
test0.py的内容如下:
txt = open("test.txt").read()
print(txt)
我们将test0.py也放入目录:
C:\Users\dyjxx\Desktop\scriptpath
后面所有的代码文件也都将放入该目录。
现在用两种方式运行test0.py。第一种运行方式是在IDLE中加载并运行test0.py;第二种方式是通过命令行来运行test0.py。
在IDLE中运行的结果如下:

通过命令行运行的结果如下:

我们发现,通过命令行方式运行test0.py的时候报错了。原因就是因为Python在寻找test.txt的时候,总是在当前目录下来找,如果找不到该文件,那么,打开一个不存在的文件肯定就会报错。
怎么样才能让它在命令行下运行不出错呢?这就需要用到当前目录。我们只需要将test.txt所在的目录 C:\Users\dyjxx\Desktop\scriptpath 设置成当前目录即可解决问题。
三、设置当前目录
直接上代码test1.py,内容如下:
import os
thepath = r"C:\Users\dyjxx\Desktop\scriptpath"
os.chdir(thepath)
txt = open("test.txt").read()
print(txt)
再看两种运行结果:


发现都没问题了,都能正常运行。
可能好奇宝宝还会问,在我们把 C:\Users\dyjxx\Desktop\scriptpath 设置成当前目录之前,当前目录又是什么呢?
我们再来看下一个程序。
四、获取当前目录
直接上代码test2.py,内容如下:
import os
thepath = r"C:\Users\dyjxx\Desktop\scriptpath"
currpath = os.getcwd()
print("当前路径:%s" % currpath)
os.chdir(thepath)
currpath2 = os.getcwd()
print("当前路径:%s" % currpath2)
txt = open("test.txt").read()
print(txt)
再看两种运行结果:


我们发现,如果Python脚本在IDLE中运行,那么,当前目录默认就是脚本所在的目录,如果是在命令行中运行,那么,Python中的当前目录就是cmd窗口中运行DOS命令的当前目录。在我们用命令强制将 C:\Users\dyjxx\Desktop\scriptpath 设置为当前目录之后,当前目录就变成了我们所希望的值。
现在,好奇宝宝可能会想到一个问题:我们写的Python脚本在运行的时候放到什么目录下都是可能的,难道每次运行都得修改Python脚本吗?有没有获取脚本所在目录的方法呢?如果有的话,我们获取到脚本所在目录,然后将其设置成当前目录,这不就搞定了?
现在让我们来看一下自动获取脚本所在目录并将其设置成当前目录的方法。
五、自动获取脚本所在目录并将其设置成当前目录
直接上代码test3.py,内容如下:
import os
# 获取当前脚本所在的目录
scriptpath = os.path.split(os.path.abspath(__file__))[0]
print("脚本路径:%s" % scriptpath)
currpath = os.getcwd()
print("当前路径:%s" % currpath)
os.chdir(scriptpath)
currpath2 = os.getcwd()
print("当前路径:%s" % currpath2)
txt = open("test.txt").read()
print(txt)
看一下两种运行方式下的运行结果:


至此,我们发现,在Python代码中如果需要读取文件,自动获取脚本所在目录并将其设置成当前目录是一个好办法。我们删掉test3.py中的测试代码,精简一下,得到test4.py。
import os
# 获取当前脚本所在的目录,并将其设置为当前目录
scriptpath = os.path.split(os.path.abspath(__file__))[0]
os.chdir(scriptpath)
# 读取文本文件并显示其内容
txt = open("test.txt").read()
print(txt)
test4.py就是一段相对完整的读取文本文件内容的代码。
六、讨论
设置当前目录的好处是要读写的文件可以不用绝对路径名来表示,这为我们带来方便。但有的时候,如果一个Python脚本import了很多自己写的模块,那么,很有可能在其中一些模块中修改了当前目录,导致另外一些模块在读写文件发生找不到文件的错误。
如何避免这种错误呢?
答案是进行文件操作时始终用绝对路径名来表示一个文件的名字。这样就可以无视当前目录了。看程序test5.py:
import os
# 获取当前脚本所在的目录,并将其设置为当前目录
scriptpath = os.path.split(os.path.abspath(__file__))[0]
# 得到文本文件的全路径名
fn = "test.txt"
fullfn = os.path.join(scriptpath, fn)
# 读取文本文件并显示其内容
txt = open(fullfn).read()
print(txt)
这里用os.path.join()函数将一个路径和一个不含路径的文件名合并成文件的全路径名。这是文件操作中经常用到的一个函数。




