如何在Python中检查目录是否存在?

1560

如何在Python中检查目录是否存在?


13
警告一下——最高评分的答案可能会受到竞态条件的影响。相反,你可能想要执行 os.stat 函数来判断目录是否同时存在且为一个目录。 - d33tah
3
@d33tah,你可能说得有道理,但我不知道如何使用os.stat来区分目录和文件。当路径无效时,它会引发OSError,无论是文件还是目录。此外,在检查后的任何代码也容易受到竞争条件的影响。 - Tomáš Zato
4
这句话的意思是:我们可以得出结论,直接执行操作并处理错误是安全的。 - d33tah
2
@David542 我添加了一个关于“isdir”和“exists”的精度澄清案例,并进行了测试。我认为你现在不会再学到什么了,但这可能会为新手提供启示。 - GeoStoneMarten
也许这个答案可以帮助你使用os.stat - Cadoiz
15个回答

2276

仅针对目录使用os.path.isdir

>>> import os
>>> os.path.isdir('new_folder')
True

使用os.path.exists判断文件和目录是否存在:

>>> import os
>>> os.path.exists(os.path.join(os.getcwd(), 'new_folder', 'file.txt'))
False

另外,您还可以使用pathlib

 >>> from pathlib import Path
 >>> Path('new_folder').is_dir()
 True
 >>> (Path.cwd() / 'new_folder' / 'file.txt').exists()
 False

4
使用括号表示对象可调用在Python并不实用,因为甚至类也是可调用的。同时,在Python中,函数是一等值,你可以不使用括号标记来使用它们,就像在existing = filter(os.path.isdir(['/lib', '/usr/lib', '/usr/local/lib'])中一样。 - phihag
11
你可以将函数传递给其他函数,比如 map,但通常情况下,你需要使用参数和括号来调用函数。另外,在你的示例中有一些错别字。推测你的意思是 filter(os.path.isdir, ['/lib', '/usr/lib', '/usr/local/lib']) - hughdbrown
5
如果你只关心路径是否是一个文件,可以使用 os.path.isfile(path) - Nicholas
3
请注意,在某些平台上,如果文件/目录存在但无读取权限,则会返回错误的结果为false。 - cowlinator
对于 pathlib 选项(我更喜欢这个选项),您也可以只使用相对路径,例如 (Path.('new_folder') / 'file.txt').exists()。要将路径解析为完全限定(绝对)路径,您可以使用 Path(...).resolve() - Cadoiz
显示剩余2条评论

122

Python 3.4引入了标准库中的pathlib模块,该模块提供了一种面向对象的处理文件系统路径的方法。通过Path对象的is_dir()exists()方法可以回答以下问题:

In [1]: from pathlib import Path

In [2]: p = Path('/usr')

In [3]: p.exists()
Out[3]: True

In [4]: p.is_dir()
Out[4]: True

可以使用/符号将路径(和字符串)连接起来:

In [5]: q = p / 'bin' / 'vim'

In [6]: q
Out[6]: PosixPath('/usr/bin/vim') 

In [7]: q.exists()
Out[7]: True

In [8]: q.is_dir()
Out[8]: False

通过PyPi上的pathlib2模块,Pathlib也可以在Python 2.7上使用。


一些解释会很有帮助。为什么要执行 "p / 'bin' / 'vim'"? - Nathan majicvr.com
1
@frank 我对答案的第二部分进行了一些详细阐述。 - joelostblom

95

非常接近了!os.path.isdir会返回True,如果你传入的是一个当前已经存在的目录名称。如果它不存在或者不是一个目录,则返回False


如果你想创建它,则os.path.isdir(路径)或os.makedirs(路径) - mins
4
使用pathlib库:Path(path).mkdir(parents=True, exist_ok=True)可以一次性创建嵌套的路径。 - Kirk Strauser

54

27
这并不检查该路径是否为目录。 - Kirk Strauser
10
好的。其他人指出os.path.isdir可以完成这个任务。 - aganders3
4
如果你明白这并不是答案,为什么不把回答删除掉呢? - user1544337
3
这个问题已经被查看了354000次(到目前为止)。这里的答案不仅适用于提问者,也适用于任何因为各种原因而来到这里的人。即使aganders3的回答不能直接解决提问者的问题,它仍然是相关的。 - Gabriel
6
@Gabriel,那么答案中应该清楚地说明这实际上是做什么的。 - user1544337
公平地说,“查找目录是否存在”的语句往往通过暗示排除非目录情况:我们有一个“概念上的目录”,它存在或不存在。这并不意味着这是考虑问题的特别“有用”方式。 - Davis Herring

26

我们可以使用两个内置函数来检查

os.path.isdir("directory")

如果指定的目录可用,它将返回布尔值true。

os.path.exists("directoryorfile")

如果指定的目录或文件存在,它将返回布尔值true。

要检查路径是否为目录;

os.path.isdir("directorypath")

如果路径是目录,将返回布尔值true。


3
这与较早的最佳答案完全重复。 - Davis Herring

22

以下代码检查您的代码中引用的目录是否存在,如果它不存在于您的工作场所中,则创建一个:

以下代码检查您的代码中引用的目录是否存在,如果不存在则创建一个:

import os

if not os.path.isdir("directory_name"):
    os.mkdir("directory_name")

pathlib.Path返回'D:\blah\blah'。但这种格式os.path无法识别。有解决的办法吗? - undefined

19

17

如果目录不存在,您可能还希望创建该目录。

Source,如果它仍然存在于SO上。

=====================================================================

在 Python ≥ 3.5 版本中,使用 pathlib.Path.mkdir 来创建目录:
from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)

针对Python的旧版本,我看到有两个答案都有很好的质量,但每个答案都有一些小缺陷,因此我会给出我的看法:

尝试使用os.path.exists,并考虑使用os.makedirs进行创建。

import os
if not os.path.exists(directory):
    os.makedirs(directory)

正如评论和其他地方所指出的那样,存在竞态条件 - 如果在os.path.exists和os.makedirs调用之间创建了目录,则os.makedirs将因OSError而失败。不幸的是,简单地捕获OSError并继续执行并不是万无一失的,因为它会忽略由于其他因素(例如权限不足、磁盘已满等)导致的无法创建目录的失败。
一个选项是捕获OSError并检查嵌入的错误代码(参见有没有一种跨平台的方法可以从Python的OSError获取信息):
import os, errno

try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

或者,可能会有第二个os.path.exists,但是假设在第一次检查后另一个人创建了该目录,然后在第二次检查之前将其删除-我们仍然可能会被愚弄。

根据应用程序的不同,同时操作的危险性可能比其他因素(如文件权限)造成的危险性更大或更小。开发人员必须在选择实现之前更多地了解正在开发的特定应用程序及其预期环境。

Python的现代版本通过公开FileExistsError(在3.3+中)等方式极大改进了此代码...

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

...并且通过允许在3.2+版本中调用os.makedirs时使用名为exist_ok的关键字参数来避免错误

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.

14

就像这样:

In [3]: os.path.exists('/d/temp')
Out[3]: True

可能加入一个os.path.isdir(...)来确保。


13

仅提供 os.stat 版本(Python 2):

import os, stat, errno
def CheckIsDir(directory):
  try:
    return stat.S_ISDIR(os.stat(directory).st_mode)
  except OSError, e:
    if e.errno == errno.ENOENT:
      return False
    raise

使用staterrno而不是pathlib2的优点是什么?这是否与d33tah在问题评论中提到的竞争条件有关? - Cadoiz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接