如何使用Python检查文件夹是否为空?

70

我正在尝试检查文件夹是否为空,并执行以下操作:

import os
downloadsFolder = '../../Downloads/'
if not os.listdir(downloadsFolder):
    print "empty"
else:
    print "not empty"

不幸的是,无论我在文件夹中是否有任何文件,我总是得到“非空”提示。这是因为可能有一些隐藏的系统文件吗?是否有一种方法可以修改上面的代码仅检查非隐藏文件?


3
当您运行print os.listdir(downloadsFolder)时,您将获得下载文件夹中所有文件和文件夹的名称列表。 - mkrieger1
正如其名,它将检查目录是否存在,而不是它是否为空。 - mkrieger1
请参考此链接:https://ubuntuforums.org/showthread.php?t=1019976 - Shrinivas Deshmukh
11个回答

76
你可以使用os模块中的这两种方法。
第一种选择:
import os
if len(os.listdir('/your/path')) == 0:
    print("Directory is empty")
else:    
    print("Directory is not empty")

第二种选择(因为空列表在Python中被评估为False):

import os
if not os.listdir('/your/path'):
    print("Directory is empty")
else:    
    print("Directory is not empty")

然而,os.listdir()可能会抛出异常,例如当给定路径不存在时。因此,您需要进行处理。

import os
dir_name = '/your/path'
if os.path.isdir(dir_name):
    if not os.listdir(dir_name):
        print("Directory is empty")
    else:    
        print("Directory is not empty")
else:
    print("Given directory doesn't exist")

我希望对你有所帮助。

请注意,即使在目录中存在'.'和'..',os.listdir(dir_name)也不包括它们。

来源:http://web.archive.org/web/20180531030548/http://thispointer.com/python-how-to-check-if-a-directory-is-empty


1
在此链接中几乎找到了完全相同的答案:https://thispointer.com/python-how-to-check-if-a-directory-is-empty/。无法找到文章的发布日期,因此无法判断其真实性。 - Rimov
@Rimov 你说得对。首先,我同意这两个代码是复制的。是的,这两种方法很相似,但对于程序员来说,代码结构和细节(甚至答案结构)非常独特。通常,小型一次性网站从StackOverflow复制代码,但这证明了另一种情况,因为......其次:文章发表于2018年4月15日,可以从Web Archive(http://web.archive.org/web/20180531030548/http://thispointer.com/python-how-to-check-if-a-directory-is-empty)中看到。我认为添加此文章链接(或较旧的文章?)作为来源将是正确的。 - Yaroslav Nikitenko
os.path.isdir(dir_name) 返回 False 也可能意味着 dir_name 是一个文件。 - undefined

40

自Python 3.5版本以来,

with os.scandir(path) as it:
    if any(it):
        print('not empty')

scandir() 通常比 listdir() 更快,因为 scandir() 是一个迭代器,不使用某些函数获取给定文件的统计信息。


1
还有Path.iterdir(),但它在底层使用listdir(),所以可能会更慢。有时,如果您的目录结构很大,您会想要使用iterdir()而不是scandir(),因为scandir()可能会消耗文件描述符资源 - ingyhere
@ingyhere,因为使用list(scandir())而不是scandir()本身,所以您在性能方面看到的差异和一般的scandir()listdir()之间的差异是不同的。根据您要处理多少个文件以及对它们的操作,scandir()listdir()可能更适合您。例如,请参阅https://bugs.python.org/issue23605. 这里的OP只需要知道目录中是否至少有1个文件,因此scandir()会更快。 - Flair
3
提示:如果目录不存在,请包含os.path.isdir检查,因为scandir会抛出异常。 - Shital Shah
谢谢!尽管scandir提供了比listdir更多的信息,但即使对于整个目录,它仍然运行得更快(从这个答案中我理解到,https://dev59.com/lrjna4cB1Zd3GeqP2wJZ)。当然,如果不需要扫描所有内容,它将运行得更快。 - Yaroslav Nikitenko
1
我想补充一点,如果在此检查后不立即退出,则最好关闭scandir迭代器。这是官方文档中推荐的做法:https://docs.python.org/3/library/os.html#os.scandir(如果不这样做,他们说会发出警告)。 - Yaroslav Nikitenko
3
@YaroslavNikitenko with 做了相同的事情,也建议在您链接的官方文档中使用。 - Flair

19

嗯,我刚试了一下你的代码,并将路径更改为空目录,它确实为我打印出了“empty”,因此您的下载文件夹中必须有隐藏文件。您可以尝试循环遍历所有文件并检查它们是否以 '.' 开头。

编辑:

尝试这个,它对我起作用了。

if [f for f in os.listdir(downloadsFolder) if not f.startswith('.')] == []:
    print "empty"
else: 
    print "not empty"

listdir() 不包括 . 或 ..。这段代码忽略了隐藏文件(例如 .gitignore),这与我所谓的空目录不一致。 - neuralmer

10

正如muskaya这里提到的那样,自Python 3.4(标准库)以来,您还可以使用pathlib。但是,如果您只想检查文件夹是否为空,则应查看此答案

from pathlib import Path

def directory_is_empty(directory: str) -> bool:
    return not any(Path(directory).iterdir())


downloadsFolder = '../../Downloads/'
if directory_is_empty(downloadsFolder):
    print "empty"
else:
    print "not empty"

7

尝试一下:

import os
dirContents = os.listdir(downloadsFolder)
if not dirContents:
    print('Folder is Empty')
else:
    print('Folder is Not Empty')

与2018年的另一个答案(https://dev59.com/9FUM5IYBdhLWcg3wINak#49284171)相比,看不出太大的区别。 - Yaroslav Nikitenko

4

扩展@Flair的答案,并加入错误处理:

您可以使用os.scandir

from os import scandir


def is_non_empty_dir(dir_name: str) -> bool:
    """
    Returns True if the directory exists and contains item(s) else False
    """
    try:
        if any(scandir(dir_name)):
            return True
    except (NotADirectoryError, FileNotFoundError):
        pass
    return False

你的回答似乎比其他答案更复杂。为什么要使用for循环? - Emmanuel-Lin
我在发现Pathlib内部使用os.scandir后修改了我的答案。 - MusKaya
我担心这样做无法捕获所有错误。我宁愿捕获OSError(包括NotADirectoryErrorFileNotFoundError)的子类。不幸的是,os.scandir不能保证只引发OSError - 然而,在https://docs.python.org/3/library/os.html#os.walk文档中暗示了这一点,因此捕获*OSError*就足够安全了。如果你省略了变量*success*和`return`,你可以节省几行代码。 - Yaroslav Nikitenko
然而,我认为假设该目录是一个真正的目录(而不是文件)会更清晰。对我来说,“是目录”和“为空”这两个概念是相当不同的(即使其中一个需要另一个)。我认为测试if is_directory(path) and is_empty_directory(path)看起来更加明确(因此更符合 Pythonic)。否则,有些人可能会认为“非空目录 => 有内容的目录”,这是错误的。此外,如果以is_开头调用它,则布尔类型提示可能是多余的(至少对于程序员而言,而不是自动工具)。希望这可以帮到您! - Yaroslav Nikitenko
谢谢Yaroslav,我有些犹豫是否要捕获一般的OSError以便能够突出显示可能出现的其他操作系统错误 :) - MusKaya

1
您可以使用以下内容验证输入文件夹中不存在任何文件:
import glob

if len(glob.glob("input\*")) == 0:
    print("No files found to Process...")
    exit()

1
我认为你可以尝试这段代码:

directory = r'path to the directory'

from os import walk

f = [] #to list the files

d = [] # to list the directories


for (dirpath, dirnames, filenames) in walk(directory):

    f.extend(filenames)
    d.extend(dirnames)
    break

if len(f) and len(d) != 0:
    print('Not empty')
else:
    print('empty')

0

另一个版本:

def is_folder_empty(dir_name):
    import os
    if os.path.exists(dir_name) and os.path.isdir(dir_name):
        return not os.listdir(dir_name)
    else:
        raise Exception(f"Given output directory {dir_name} doesn't exist")

0

简而言之(适用于 Python 3.10.4):if not os.listdir(dirname): ...

这里有一个快速演示:

$ rm -rf BBB
$ mkdir BBB
$ echo -e "import os\nif os.listdir(\"BBB\"):\n  print(\"non-empty\")\nelse:\n  print(\"empty\")" > empty.py
$ python empty.py
empty
$ echo "lorem ipsum" > BBB/some_file.txt
$ python empty.py
non-empty
$ rm BBB/some_file.txt 
$ python empty.py
empty

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