数字营销 · Web开发 · 基础设施

Python中os.path.isfile()和os.path.isdir()均返回false的问题

记录使用 Python 自动备份目录时遇到的路径判断问题,以及通过 os.path.join() 组合完整路径的解决方法。

提示:本文写于 2013 年,文中使用的 Python 版本、代码及 Linux 环境均基于当时的实际开发环境,请结合文章发布时间阅读。

今天在写一个 Linux 下自动备份指定目录中所有目录的脚本时,遇到了一个问题。

因为我需要备份的是目录,所以首先需要判断扫描到的文件是不是目录。

但是,当我使用:

os.path.isdir()

进行判断的时候,发现所有文件返回的结果都是 False

刚开始的时候,我以为可能是系统兼容性的问题。

进一步测试之后发现,使用:

os.path.isfile()

这些文件同样返回 False

这时候基本可以确定,不是系统的问题,而是程序本身的写法有问题。

代码如下:

#!/usr/bin/env python
# a python script to auto backup a directory's file by Hito

import os

Directory = raw_input(
"Please enter directory you want to backup:"
)

dirs = os.listdir(Directory)

for filename in dirs:

if os.path.isdir(filename):

os.system(
"tar czvf " +
filename +
".tar.gz " +
filename
)

问题出在哪里?

经过仔细排查,发现问题出在:

os.listdir(Directory)

这里。

os.listdir() 返回的只是指定目录中的文件名,而不是这些文件的完整路径。

例如,如果:

Directory = /home/hito/backup

目录下面有:

test
www
data

那么:

dirs=os.listdir(Directory)

得到的实际上只是:

test
www
data

而不是:

/home/hito/backup/test
/home/hito/backup/www
/home/hito/backup/data

所以,在下面的代码中:

os.path.isdir(filename)

Python 实际上是在当前工作目录中查找:

test
www
data

而这些目录并不一定存在于当前工作目录,因此自然会返回 False

进一步测试也可以发现,如果直接传入目录的完整路径:

os.path.isdir("/home/hito/backup/test")

就可以正常返回 True

这里的问题并不是 isdir() 本身不能处理相对路径,而是:

filename 只是 os.listdir() 返回的文件名,它并不是我们刚才输入的 Directory 下面的完整路径。

使用 os.path.join()

那么这个备份脚本应该怎么修改呢?Python 提供了一个非常方便的:

os.path.join()

函数。

它可以自动把目录和文件名组合成完整路径,也不用自己手动拼接字符串,更不用担心路径之间多出或者少了 /

所以,备份脚本可以这样修改:

#!/usr/bin/env python
# a python script to auto backup a directory's file by Hito

import os

Directory = raw_input(
"Please enter directory you want to backup:"
)

dirs = os.listdir(Directory)

for filename in dirs:

fulldirfile = os.path.join(
Directory,
filename
)

if os.path.isdir(fulldirfile):

os.system(
"tar czvf " +
fulldirfile +
".tar.gz " +
fulldirfile
)

这样:

os.path.join(Directory, filename)

得到的就是对应文件或者目录的完整路径。

再通过:

os.path.isdir(fulldirfile)

进行判断,就可以正确识别指定目录下的子目录了。

这个问题虽然比较简单,但是在使用 os.listdir() 的时候还是需要注意:

它返回的是目录中的名称,而不是带有目录路径的完整文件名。

所以,在需要进一步判断或者操作这些文件的时候,通常还需要把原来的目录路径和文件名组合起来。

评论0

欢迎分享你的看法,也欢迎补充不同的实践经验。