如何检查文件是否存在,没有异常?

How do I check whether a file exists without exceptions?

提问人:spence91 提问时间:9/17/2008 最后编辑:syntagmaspence91 更新时间:12/22/2022 访问量:5329250

问:

如何在不使用 try 语句的情况下检查文件是否存在?

python 文件 文件存在

评论

1赞 masterxilo 11/19/2023
注意:如果程序无法处理文件已经存在或在您实际尝试打开或创建文件时不存在的情况,则您的程序将不是 100% 健壮的。文件系统可由多个程序同时访问,因此在执行这些操作之前执行的存取检查在程序对其执行操作时可能已经过时。

答:

879赞 Paul 9/17/2008 #1
import os

if os.path.isfile(filepath):
   print("File exists")
360赞 benefactual 9/17/2008 #2
import os
os.path.exists(path) # Returns whether the path (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not

评论

10赞 Homunculus Reticulli 4/4/2020
通常,将变量命名为与方法名称相同的方法并不好。
2601赞 PierreBdR 9/17/2008 #3

使用 os.path.exists 检查文件和目录:

import os.path
os.path.exists(file_path)

使用 os.path.isfile 仅检查文件(注意:遵循符号链接):

os.path.isfile(file_path)
6483赞 rslite 9/17/2008 #4

如果您要检查的原因是您可以执行类似 之类的操作,则使用周围尝试打开它更安全。检查然后打开文件可能会被删除或移动,或者在检查和尝试打开文件之间发生某些风险。if file_exists: open_it()try

如果您不打算立即打开该文件,可以使用 os.path.isfile

如果 path 是现有的常规文件,则返回。这遵循符号链接,因此对于同一路径,islink() 和 isfile() 都可以为 true。True

import os.path
os.path.isfile(fname)

如果您需要确定它是一个文件。

从 Python 3.4 开始,pathlib 模块提供了一种面向对象的方法(在 Python 2.7 中向后移植):pathlib2

from pathlib import Path

my_file = Path("/path/to/file")
if my_file.is_file():
    # file exists

要检查目录,请执行以下操作:

if my_file.is_dir():
    # directory exists

要检查对象是否独立于文件或目录而存在,请使用:Pathexists()

if my_file.exists():
    # path exists

您还可以在块中使用:resolve(strict=True)try

try:
    my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
    # doesn't exist
else:
    # exists

评论

86赞 makapuf 6/20/2018
关于第一个评论(如果在打开之前检查,请使用“try”),不幸的是,如果您想打开附加并确保它之前存在,这将不起作用,因为如果不存在,将创建“a”模式。
19赞 scottclowe 3/29/2019
请注意,这是在 Python 3 中引入的。如果您还需要支持 Python 2.7 和 Python 3,则可以改用(哪些子类)stackoverflow.com/a/21368457/1960959FileNotFoundErrorIOErrorFileNotFoundError
20赞 kyrill 5/1/2019
@makapuf 您可以打开它进行“更新”(),然后搜索到最后。open('file', 'r+')
2赞 theX 7/3/2020
等等,那<? 适用于 python3,对吧?我一直在认为它更优越。pathlib2pathlibpathlibpathlib2
6赞 hagello 11/20/2020
@kyrill:打开文件进行追加与打开文件进行写入并寻找到最后是不一样的:当你有并发编写器时,它们会在没有.'a'
41赞 zgoda 9/17/2008 #5

此外:os.access()

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()

是 、 和用于测试权限的标志 (doc)。R_OKW_OKX_OK

1224赞 bortzmeyer 9/17/2008 #6

isfile() 不同,exists() 将返回目录。因此,根据您是只想要普通文件还是目录,您将使用 或 .以下是一些简单的 REPL 输出:Trueisfile()exists()

>>> os.path.isfile("/etc/password.txt")
True
>>> os.path.isfile("/etc")
False
>>> os.path.isfile("/does/not/exist")
False
>>> os.path.exists("/etc/password.txt")
True
>>> os.path.exists("/etc")
True
>>> os.path.exists("/does/not/exist")
False
142赞 pkoch 11/4/2009 #7

首选 try 语句。它被认为是更好的风格,并避免了比赛条件。

不要相信我的话。这个理论有很多支持。这是一对夫妇:

评论

4赞 BlueTrin 9/10/2015
请添加更好的来源来支持您的陈述。
12赞 jstine 9/28/2015
引用的避免竞争条件(苹果开发支持)链接不支持您的答案。它只涉及在设计不佳的操作系统上使用包含敏感信息的临时文件,这些操作系统无法通过受限权限正确沙盒临时文件/目录。无论如何,使用都无助于解决这个问题try...except
0赞 Camion 5/24/2019
此方法的问题在于,如果您有一段重要的代码依赖于不存在的文件,则将其放在子句中将导致代码的这一部分中出现的异常将引发令人困惑的消息(在处理第一个错误期间引发的第二个错误)。except:
0赞 Ben Farmer 5/25/2023
但是通常使用上下文管理器打开文件,并且许多软件包似乎没有实现它们,只有非常好的例外。例如,xarray 只是抛出一个超级通用的“ValueError”,如果你尝试打开一个文件夹而不是一个 netcdf 文件,就会有一些关于后端的令人困惑的消息。在此处捕获 ValueError 可能会掩盖各种其他问题。
67赞 philberndt 1/26/2011 #8

你可以试试这个(更安全):

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

输出将是:

([Errno 2] 没有这样的文件或目录: '随便.txt')

然后,根据结果,您的程序可以从那里继续运行,或者您可以根据需要编写代码来停止它。

评论

22赞 rrs 4/23/2014
最初的问题要求一个不使用try
8赞 Chris Johnson 2/18/2016
这个答案没有抓住OP的重点,检查文件是否存在与检查是否可以打开它不同。在某些情况下,文件确实存在,但由于各种原因,您无法打开它。
7赞 2 revs, 2 users 67%aitchnyu #9
import os
path = /path/to/dir

root,dirs,files = os.walk(path).next()
if myfile in files:
   print "yes it exists"

这在检查多个文件时很有帮助。或者您想对现有列表进行设置交集/减法。

评论

4赞 Chris Johnson 6/14/2017
这在两个方面是错误的:(1)在目录树下查找所有文件 - 如果用户想要检查,他不太可能希望将其视为匹配项,而您的解决方案确实如此;(2)在当前目录下有许多文件的情况下,与简单调用相比,您的解决方案效率非常低。如果树中不存在匹配的 filename-without-path,则代码将在返回 false 之前枚举树中的每个文件。os.walk./FILE./some/sub/folder/FILEos.path.isfile()
426赞 Yugal Jindle 1/16/2012 #10

os.path.isfile() 与 os.access() 一起使用:

import os

PATH = './file.txt'
if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print("File exists and is readable")
else:
    print("Either the file is missing or not readable")

评论

75赞 wim 4/9/2013
具有多个条件,其中一些是多余的,不太清楚和明确。
19赞 user207421 3/13/2018
这也是多余的。如果文件不存在,将返回 false。os.access()
12赞 e-info128 7/17/2018
@EJP 在 linux 中,文件可以存在,但不能访问。
13赞 Jester 8/24/2018
既然你,你就不需要再来了,因为它已经是 的一部分。如果您只打算使用函数 from 而不是 from 本身,则只需要导入,以导入较小的内容,但是当您使用 and 时,不需要第二次导入。import osimport os.pathosos.pathos.pathosos.accessos.R_OK
7赞 Martin Meeser 7/2/2020
检查用户是否具有读取文件的访问权限非常专业。在开发期间,数据通常位于本地驱动器上,而在生产过程中则位于网络共享上。那么这可能会导致这种情况。此外,代码非常清晰、可读且明确。
174赞 Val Neekman 6/27/2013 #11

这是检查文件是否存在的最简单方法。仅仅因为您检查时文件存在并不能保证当您需要打开它时它会在那里。

import os
fname = "foo.txt"
if os.path.isfile(fname):
    print("file does exist at this time")
else:
    print("no such file exists at this time")

评论

18赞 Isaac Supeene 11/24/2014
只要您打算访问该文件,竞争条件就确实存在,而不管您的程序是如何构造的。您的程序不能保证计算机上的其他进程没有修改该文件。这就是埃里克·利珀特(Eric Lippert)所说的外生例外。您无法通过事先检查文件是否存在来避免它。
1赞 Val Neekman 7/28/2018
@IsaacSupeene 最佳做法是使(文件)操作的窗口尽可能小,然后进行适当的异常处理
0赞 Anders Lindén 8/31/2021
最好的方法是使用 try+catch 打开文件,并且没有时间窗口。
77赞 chad 9/25/2013 #12

try/except 和 之间似乎没有有意义的功能差异,因此您应该使用哪一个有意义。isfile()

如果要读取文件,如果存在,请执行

try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

但是,如果您只想重命名一个文件(如果它存在),因此不需要打开它,请执行

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

如果要写入文件,如果它不存在,请执行

# Python 2
if not os.path.isfile(filepath):
    f = open(filepath, 'w')

# Python 3: x opens for exclusive creation, failing if the file already exists
try:
    f = open(filepath, 'wx')
except IOError:
    print 'file already exists'

如果您需要文件锁定,那是另一回事。

评论

5赞 Chris Johnson 8/1/2015
这个答案是错误的。 对于非文件的内容(如目录)返回 true。这会产生误报。请参阅其他建议的答案。os.path.existsos.path.isfile
6赞 spectras 8/24/2015
在您的第三个示例中,我创建了一个以正确时间命名的链接,而 BAM 将覆盖目标文件。您应该在块中执行以避免该问题。filepathopen(filepath, 'wx')try...except
1赞 Tom Myddeltyn 5/24/2016
在您的第二个示例中,至少在 Windows 中,您将得到一个 if already exists:“在 Windows 上,如果 dst 已经存在,即使它是一个文件,也会引发 OSError;当 DST 命名现有文件时,可能无法实现原子重命名。OSErrorfilepath + '.old'
0赞 ShadowRanger 11/30/2017
@TomMyddeltyn:从 Python 3.3 开始,os.replace 可移植地执行目标文件的静默替换(它与 Linux 行为相同)(仅当目标名称存在并且是目录时才会出错)。所以你被困在 2.x 上,但 Py3 用户已经有好几年了。os.rename
0赞 ShadowRanger 11/30/2017
在示例中:它仍然应该用 / 来完成。 (或在现代 Python 上)是原子的;选中它,然后重命名会引入不必要的争用和额外的系统调用。只是做renametryexceptos.renameos.replacetry: os.replace(filepath, filepath + '.old') except OSError: pass
220赞 Cody Piersall 2/8/2014 #13

Python 3.4+ 有一个面向对象的路径模块:pathlib。使用这个新模块,您可以检查文件是否存在,如下所示:

import pathlib
p = pathlib.Path('path/to/file')
if p.is_file():  # or p.is_dir() to see if it is a directory
    # do stuff

打开文件时,您仍然可以(通常应该)使用块:try/except

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

pathlib 模块中有很多很酷的东西:方便的通配、检查文件的所有者、更容易的路径连接等。值得一试。如果您使用的是较旧的 Python(版本 2.6 或更高版本),您仍然可以使用 pip 安装 pathlib:

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

然后按如下方式导入它:

# Older Python versions
import pathlib2 as pathlib

评论

0赞 Ryan Haining 10/12/2020
您可以使用 pathlib。Path.exists,它涵盖的案例比is_file
20赞 Chris 2/11/2014 #14

你可以写 Brian 的建议,而不用 .try:

from contextlib import suppress

with suppress(IOError), open('filename'):
    process()

suppress是 Python 3.4 的一部分。在旧版本中,您可以快速编写自己的抑制:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass
6赞 Zaheer 5/23/2014 #15

您可以使用以下 open 方法来检查文件是否存在 + 可读:

file = open(inputFile, 'r')
file.close()

评论

8赞 Sam Dolan 2/20/2020
如果文件不存在,这肯定会引发异常。
0赞 Peter Mortensen 10/5/2022
问题是“如何检查文件是否存在而没有异常?
44赞 bergercookie 10/13/2014 #16

如果文件用于打开,则可以使用以下方法之一:

with open('somefile', 'xt') as f: # Using the x-flag, Python 3.3 and above
    f.write('Hello\n')

if not os.path.exists('somefile'): 
    with open('somefile', 'wt') as f:
        f.write("Hello\n")
else:
    print('File already exists!')

注意:这将查找具有给定名称的文件目录。

评论

10赞 Chris Johnson 8/1/2015
这个答案是错误的。 对于非文件的内容(如目录)返回 true。这会产生误报。请参阅其他建议的答案。os.path.existsos.path.isfile
0赞 Zorglub29 5/20/2018
也遇到了误报问题。
0赞 JayRizzo 9/1/2018
docs.python.org/3/library/os.path.html#os.path.exists 对于上述来自 chris >>os.path.exists(path) 的语句,>如果 path 引用现有路径或打开的文件描述符,则返回 True。对于损坏的符号链接,返回 False。在某些平台上,如果未授予对请求的文件执行 os.stat() 的权限,则此函数可能会返回 False,即使路径实际存在。在 3.3 版更改: path 现在可以是整数:如果它是打开的文件描述符,则返回 True,否则返回 False。在 3.6 版更改: 接受类似路径的对象。
7赞 Hanson 10/18/2014 #17

要检查文件是否存在,

from sys import argv

from os.path import exists
script, filename = argv
target = open(filename)
print "file exists: %r" % exists(filename)

评论

7赞 Pavel Chernikov 8/23/2015
Exists 不区分文件和目录。os.path.isfile 是检查文件是否存在的更好方法。
14赞 Pradip Das 12/20/2014 #18

您可以使用 Python 的 “OS” 库:

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False

评论

6赞 Chris Johnson 8/1/2015
这个答案是错误的。 对于非文件的内容(如目录)返回 true。这会产生误报。请参阅其他建议的答案。os.path.existsos.path.isfile
0赞 Pradip Das 8/2/2015
@Chris Johnson , os.path.exists() 函数检查系统中是否存在路径。PATH 可以是 DIRECTORY 或 FILE。它在这两种情况下都可以正常工作。请尝试一些例子
0赞 Debosmit Ray 4/15/2016
所以,这个答案有效。伟大。如果路径不是文件的路径。这就是问题所在吗?不。
0赞 starturtle 9/5/2017
这要视情况而定。如果确定“文件”是否存在的目标是找出该路径是否已经存在(因此不是可以在不删除其他信息的情况下存储新数据的路径),那么就可以了。如果目标是确定打开一个可能存在的文件是否安全,那么批评是有道理的,并且存在不够精确。可悲的是,OP 没有指定哪个是期望的目标(并且可能不会再这样做了)。exists
54赞 Zizouz212 12/27/2014 #19

虽然我总是推荐使用 和 语句,但这里有一些可能性供您使用(我个人最喜欢的是使用):tryexceptos.access

  1. 尝试打开文件:

    打开文件将始终验证文件是否存在。你可以像这样制作一个函数:

    def File_Existence(filepath):
        f = open(filepath)
        return True
    

    如果为 False,它将使用未处理的 IOError 停止执行 或 OSError。要捕获异常, 您必须使用 try except 子句。当然,你总是可以 像这样使用 except' 语句(感谢 Hsandt 让我思考):try

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
    
  2. 用:os.path.exists(path)

    这将检查您指定的内容是否存在。但是,它会检查文件目录,因此请注意如何使用它。

    import os.path
    >>> os.path.exists("this/is/a/directory")
    True
    >>> os.path.exists("this/is/a/file.txt")
    True
    >>> os.path.exists("not/a/directory")
    False
    
  3. 用:os.access(path, mode)

    这将检查您是否有权访问该文件。它将检查权限。根据 os.py 文档,键入 ,它将检查路径是否存在。但是,使用此功能会造成安全漏洞,因为有人可能会利用检查权限和打开文件之间的时间来攻击您的文件。相反,您应该直接打开文件,而不是检查其权限。(EAFPLBYP)。如果您之后不打算打开该文件,而只是检查它的存在,那么您可以使用它。os.F_OK

    无论如何,这里:

    >>> import os
    >>> os.access("/is/a/file.txt", os.F_OK)
    True
    

我还应该提到,有两种方法可以验证文件的存在。问题要么是 ,要么是 .如果您遇到 ,请设置 (就像我的第一个选项一样),然后输入,以便您有希望确定您的问题。希望对您有所帮助!:)permission deniedno such file or directoryIOErrorIOError as eprint(e.args)

26赞 Pedro Lobito 4/28/2015 #20
if os.path.isfile(path_to_file):
    try:
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

引发异常被认为是可以接受的,而 Pythonic, 程序中的流量控制方法。考虑处理缺失 文件。在此情况下,IOError 异常将是 如果文件存在但用户没有读取权限,则引发。

来源: 使用 Python: 如何检查文件是否存在

评论

6赞 Chris Johnson 2/18/2016
OP 询问如何检查文件是否存在。文件可能存在,但您无法打开它。因此,使用打开文件作为代理来检查文件是否存在是不正确的:将产生漏报。
110赞 incalite 5/26/2015 #21

用:

import os
#Your path here e.g. "C:\Program Files\text.txt"
#For access purposes: "C:\\Program Files\\text.txt"
if os.path.exists("C:\..."):
    print "File found!"
else:
    print "File not found!"

通过导入,可以更轻松地在操作系统中导航和执行标准操作。os

有关参考,另请参阅如何检查文件是否存在且没有异常?

如果需要高级操作,请使用 .shutil

评论

15赞 Chris Johnson 8/1/2015
这个答案是错误的。 对于非文件的内容(如目录)返回 true。这会产生误报。请参阅其他建议的答案。os.path.existsos.path.isfile
10赞 Khaled.K 8/5/2015 #22
import os.path

def isReadableFile(file_path, file_name):
    full_path = file_path + "/" + file_name
    try:
        if not os.path.exists(file_path):
            print "File path is invalid."
            return False
        elif not os.path.isfile(full_path):
            print "File does not exist."
            return False
        elif not os.access(full_path, os.R_OK):
            print "File cannot be read."
            return False
        else:
            print "File can be read."
            return True
    except IOError as ex:
        print "I/O error({0}): {1}".format(ex.errno, ex.strerror)
    except Error as ex:
        print "Error({0}): {1}".format(ex.errno, ex.strerror)
    return False
#------------------------------------------------------

path = "/usr/khaled/documents/puzzles"
fileName = "puzzle_1.txt"

isReadableFile(path, fileName)

评论

0赞 Khaled.K 8/9/2015
@j6m8 yes,如果文件可由 process\program\thread 访问和读取,则返回isReadableFile(path,fileName)True
144赞 Russia Must Remove Putin 8/11/2015 #23

如何在不使用 try 语句的情况下使用 Python 检查文件是否存在?

现在从 Python 3.4 开始可用,导入并实例化带有文件名的对象,并检查方法(请注意,对于指向常规文件的符号链接,这也返回 True):Pathis_file

>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

如果您使用的是 Python 2,则可以从 pypi、pathlib2 向后移植 pathlib 模块,或者从模块中检查:isfileos.path

>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

现在,上面可能是这里最好的实用直接答案,但存在竞争条件的可能性(取决于您要完成的任务),并且底层实现使用 ,但 Python 在其实现中无处不在。trytry

因为 Python 无处不在,所以真的没有理由避免使用它的实现。try

但这个答案的其余部分试图考虑这些警告。

更长、更迂腐的答案

从 Python 3.4 开始可用,请使用 中的新对象。请注意,这并不完全正确,因为目录不是文件(除非在 unix 意义上,一切都是文件)。Pathpathlib.exists

>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

所以我们需要使用:is_file

>>> root.is_file()
False

这是帮助:is_file

is_file(self)
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).

因此,让我们得到一个我们知道是文件的文件:

>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True

默认情况下,在关闭时删除文件(当不再有对文件的引用时,将自动关闭)。NamedTemporaryFile

>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

但是,如果您深入研究实现,您会看到它使用:is_filetry

def is_file(self):
    """
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).
    """
    try:
        return S_ISREG(self.stat().st_mode)
    except OSError as e:
        if e.errno not in (ENOENT, ENOTDIR):
            raise
        # Path doesn't exist or is a broken symlink
        # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
        return False

竞争条件:我们为什么喜欢尝试

我们喜欢,因为它避免了竞争条件。使用 ,您只需尝试读取文件,期望它在那里,如果没有,则捕获异常并执行任何有意义的回退行为。trytry

如果你想在尝试读取文件之前检查它是否存在,并且你可能正在删除它,然后你可能正在使用多个线程或进程,或者另一个程序知道该文件并可能删除它 - 如果你检查它存在,你就有可能出现争用条件,因为你正在竞相在其条件(它的存在)改变之前打开它。

竞争条件很难调试,因为在一个非常小的窗口内,它们可能会导致程序失败。

但是,如果这是您的动机,则可以使用上下文管理器来获取语句的值。trysuppress

避免在没有 try 语句的情况下出现争用条件:suppress

Python 3.4 为我们提供了 suppress 上下文管理器(以前是 ignore context manager),它在语义上以更少的行数执行完全相同的事情,同时(至少在表面上)满足了原始要求以避免语句:try

from contextlib import suppress
from pathlib import Path

用法:

>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
... 
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
... 
>>> 

对于早期的 Python,您可以滚动自己的 ,但没有 will 比 with 更冗长。我确实相信这实际上是唯一一个在 Python 3.4 之前可以应用于 Python 的任何级别的 try 不使用 try 的答案,因为它使用上下文管理器来代替:suppresstry

class suppress(object):
    def __init__(self, *exceptions):
        self.exceptions = exceptions
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            return issubclass(exc_type, self.exceptions)

也许尝试一下会更容易:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass

其他不符合“不尝试”要求的选项:

is文件

import os
os.path.isfile(path)

文档中:

os.path.isfile(path)

如果 path 是现有的常规文件,则返回 True。这遵循符号 链接,因此对于同一路径,两者都可以为 true。islink()isfile()

但是,如果你检查这个函数的源代码,你会发现它实际上使用了 try 语句:

# This follows symbolic links, so both islink() and isdir() can be true
# for the same path on systems that support symlinks
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)
>>> OSError is os.error
True

它所做的只是使用给定的路径来查看它是否可以获取统计信息,捕获并检查它是否是一个文件(如果它没有引发异常)。OSError

如果您打算对文件执行某些操作,我建议直接尝试尝试 - 除了避免竞争条件:

try:
    with open(path) as f:
        f.read()
except OSError:
    pass

操作系统.access

可用于 Unix 和 Windows 的是 ,但要使用,您必须传递标志,并且它不区分文件和目录。这更用于测试真正的调用用户是否在提升的权限环境中具有访问权限:os.access

import os
os.access(path, os.F_OK)

它还存在与 相同的竞争条件问题。从文档中:isfile

注意: 使用 access() 检查用户是否被授权,例如打开文件 在实际执行此操作之前,使用 open() 会创建一个安全漏洞,因为 用户可能会利用检查和 打开文件进行操作。最好使用 EAFP 技术。例如:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"

最好写成:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

避免使用 .它是一个低级函数,与上面讨论的高级对象和函数相比,它有更多的用户错误机会。os.access

对另一个答案的批评:

另一个答案是这样说的:os.access

就我个人而言,我更喜欢这个,因为在后台,它调用本机 API(通过“${PYTHON_SRC_DIR}/Modules/posixmodule.c”),但它也为可能的用户错误打开了大门,而且它不像其他变体那样 Pythonic:

这个答案说它更喜欢非 Pythonic 的、容易出错的方法,没有理由。它似乎鼓励用户在不了解低级 API 的情况下使用它们。

它还创建了一个上下文管理器,通过无条件返回 ,允许所有异常(包括和!)静默传递,这是隐藏错误的好方法。TrueKeyboardInterruptSystemExit

这似乎鼓励用户采用不良做法。

19赞 Love and peace - Joe Codeswell 8/30/2015 #24

下面是用于 Linux 命令行环境的单行 Python 命令。我发现这非常方便,因为我不是一个很热的 Bash 家伙。

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

评论

9赞 flotzilla 10/1/2015
bash: 中的单行检查:(与 相同)。[ -f "${file}" ] && echo "file found" || echo "file not found"if [ ... ]; then ...; else ...; fi
2赞 ruohola 10/25/2021
对于命令行上的这项工作,Python 将是一个完全错误的工具。
0赞 Love and peace - Joe Codeswell 10/27/2021
嗨,@ruohola :)我不同意。
1赞 Peter Mortensen 10/5/2022
在 Python 中的单行代码上:“......这使得 Python 对于命令行单行程序几乎毫无用处......你可以用一系列简单的语句来摆脱,用分号分隔......一旦你添加了一个引入缩进块的构造(如 if),你就需要换行符......”
84赞 KaiBuxe 2/24/2016 #25

在2016年,最好的方法仍然是使用:os.path.isfile

>>> os.path.isfile('/path/to/some/file.txt')

或者在 Python 3 中,您可以使用:pathlib

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...

评论

4赞 KaiBuxe 2/25/2016
pathlib是 python 的路径 OOP 解决方案。你可以用它做更多的事情。如果你只需要检查存在性,优势就没有那么大了。
19赞 Mike McKerns 5/5/2016 #26

我是一个已经存在了大约 10 年的软件包的作者,它有一个直接解决这个问题的功能。基本上,如果您使用的是非 Windows 系统,它用于访问 .但是,如果您使用的是 Windows,它会使用高效的文件系统遍历器进行复制。Popenfindfind

代码本身不使用块...除了确定操作系统,从而引导您到“Unix”风格或手工构建。时序测试表明,在确定操作系统方面速度更快,所以我确实在那里使用了一个(但在其他地方没有)。tryfindfindtry

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

而医生...

>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

    patterns: name or partial name string of items to search for
    root: path string of top-level directory to search
    recurse: if True, recurse down from root directory
    type: item filter; one of {None, file, dir, link, socket, block, char}
    verbose: if True, be a little verbose about the search

    On some OS, recursion can be specified by recursion depth (an integer).
    patterns can be specified with basic pattern matching. Additionally,
    multiple patterns can be specified by splitting patterns with a ';'
    For example:
        >>> find('pox*', root='..')
        ['/Users/foo/pox/pox', '/Users/foo/pox/scripts/pox_launcher.py']

        >>> find('*shutils*;*init*')
        ['/Users/foo/pox/pox/shutils.py', '/Users/foo/pox/pox/__init__.py']

>>>

如果你愿意看的话,实现在这里:https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190

6赞 iPhynx 6/8/2016 #27

您可以使用 os.listdir 来检查文件是否在某个目录中。

import os
if 'file.ext' in os.listdir('dirpath'):
    #code

评论

3赞 Jean-François Fabre 1/7/2017
在 Windows 中不起作用,因为文件系统不区分大小写。而且非常无效,因为它扫描了整个目录。
17赞 Marcel Wilson 8/5/2016 #28

再添加一个细微的变化,这在其他答案中并没有完全反映出来。

这将处理 being 或空字符串的情况。file_pathNone

def file_exists(file_path):
    if not file_path:
        return False
    elif not os.path.isfile(file_path):
        return False
    else:
        return True

根据 Shahbaz 的建议添加变体

def file_exists(file_path):
    if not file_path:
        return False
    else:
        return os.path.isfile(file_path)

根据 Peter Wood 的建议添加变体

def file_exists(file_path):
    return file_path and os.path.isfile(file_path):

评论

4赞 Shahbaz 1/5/2017
if (x) return true; else return false;真的只是.你的最后四行可以变成 .当我们使用它时,整个函数可以简化为 .return xreturn os.path.isfile(file_path)return file_path and os.path.isfile(file_path)
0赞 Marcel Wilson 1/6/2017
在 的情况下,您必须小心。Python 将考虑一个空字符串 False,在这种情况下,我们将返回一个空字符串而不是布尔值。此函数的目的是始终返回 bool。return xif (x)
1赞 Shahbaz 1/6/2017
真。然而,在这种情况下,它已经是布尔了。xos.path.isfile(..)
0赞 Marcel Wilson 1/6/2017
os.path.isfile(None)引发异常,这就是我添加 if 检查的原因。我可能只是把它包装在一个尝试/除了中,但我觉得这样更明确。
4赞 Peter Wood 4/6/2017
return file_path and os.path.isfile(file_path)
102赞 Tom Fuller 10/8/2016 #29

使用 和 测试文件和文件夹os.path.isfile()os.path.isdir()os.path.exists()

假设“path”是有效路径,下表显示了每个函数为文件和文件夹返回的内容:

enter image description here

您还可以测试文件是否是用于获取扩展名的某种类型的文件(如果您还不知道)os.path.splitext()

>>> import os
>>> path = "path to a word document"
>>> os.path.isfile(path)
True
>>> os.path.splitext(path)[1] == ".docx" # test if the extension is .docx
True
15赞 Taufiq Rahman 12/2/2016 #30

如何在不使用 try 语句的情况下检查文件是否存在?

在 2016 年,这仍然可以说是检查文件是否存在以及是否为文件的最简单方法:

import os
os.path.isfile('./file.txt')    # Returns True if exists, else False

isfile实际上只是一个内部使用和下面的辅助方法。这是一种较低级别的方法,可为您提供有关文件、目录、套接字、缓冲区等的详细信息。有关 os.stat 的更多信息,请点击此处os.statstat.S_ISREG(mode)os.stat

注意:但是,此方法不会以任何方式锁定文件,因此您的代码可能容易受到“检查时间到使用时间”(TOCTTOU)错误的影响。

因此,引发异常被认为是程序中可接受的 Python 流控制方法。应该考虑使用 IOErrors 处理丢失的文件,而不是语句(只是一个建议)。if

309赞 CristiFati 6/21/2017 #31

尽管几乎所有可能的方法都已在现有答案中列出(至少一种)(例如,添加了 Python 3.4 特定的东西),但我会尝试将所有内容组合在一起。

注意:我将要发布的每段 Python 标准库代码都属于 3.5.3 版本。

问题陈述

  1. 检查文件(可争辩:也是文件夹(“特殊”文件)?)是否存在

  2. 不要使用 try / except / else / finally

可能的解决方案

1. [Python.Docs]:os.path.exists(路径)

还要检查其他函数系列成员,如 os.path.isfile、os.path.isdir、os.path.lexists,了解其行为是否略有不同:

如果 path 引用现有路径或打开的文件描述符,则返回。返回断开的符号链接。在某些平台上,如果未授予对请求的文件执行 os.stat() 的权限,即使路径实际存在,此函数也可能会返回。TrueFalseFalse

一切都很好,但是如果遵循导入树:

  • os.path - posixpath.pyntpath.py)

    • genericpath.py - 线路 ~20+

      def exists(path):
          """Test whether a path exists.  Returns False for broken symbolic links"""
          try:
              st = os.stat(path)
          except os.error:
              return False
          return True
      

它只是 [Python.Docs] 周围的一个尝试/除外:os.stat(path, *, dir_fd=None, follow_symlinks=True)。因此,您的代码是 try / except free,但在帧堆栈的较低位置(至少)有一个这样的块。这也适用于其他函数(包括 os.path.isfile)。

1.1. [Python.Docs]:pathlib - Path.is_file()
  • 这是一种更高级(更[维基词典]:Pythonic)处理路径的方式,但是

  • 在引擎盖下,它做完全相同的事情(pathlib.py - 行 ~1330):

    def is_file(self):
        """
        Whether this path is a regular file (also True for symlinks pointing
            to regular files).
        """
        try:
            return S_ISREG(self.stat().st_mode)
        except OSError as e:
            if e.errno not in (ENOENT, ENOTDIR):
                raise
            # Path doesn't exist or is a broken symlink
            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
            return False
    

2. [Python.Docs]:使用语句上下文管理器

也:

  • 创建一个:

    class Swallow:  # Dummy example
        swallowed_exceptions = (FileNotFoundError,)
    
        def __enter__(self):
            print("Entering...")
    
        def __exit__(self, exc_type, exc_value, exc_traceback):
            print("Exiting:", exc_type, exc_value, exc_traceback)
            # Only swallow FileNotFoundError (not e.g. TypeError - if the user passes a wrong argument like None or float or ...)
            return exc_type in Swallow.swallowed_exceptions
    
    • 及其用法 - 我将复制 os.path.isfile 行为(请注意,这仅用于演示目的,不要尝试为生产编写此类代码):

      import os
      import stat
      
      
      def isfile_seaman(path):  # Dummy func
          result = False
          with Swallow():
              result = stat.S_ISREG(os.stat(path).st_mode)
          return result
      
  • 使用 [Python.Docs]: contextlib.suppress(*exceptions) - 专为选择性抑制异常而设计


但是,它们似乎是 try / except / else / finally 块的包装器,如 [Python.Docs]: 复合语句 - with 语句指出:

这允许常见的尝试...除了...最后,使用模式要封装,以便于重用。

3. 文件系统遍历函数

在结果中搜索匹配项:

  1. [Python.Docs]:os.listdir(path='.')(或 Python v3.5+ 上的 [Python.Docs]: os.scandir(path='.'),向后移植:[PyPI]:scandir)

    使用 scandir() 而不是 listdir() 可以显著提高同样需要文件类型或文件属性信息的代码的性能,因为 os.如果操作系统在扫描目录时提供此信息,则 DirEntry 对象会公开此信息。所有操作系统。DirEntry 方法可以执行系统调用,但 is_dir() 和 is_file() 通常只需要对符号链接进行系统调用;操作系统。DirEntry.stat() 在 Unix 上始终需要系统调用,但在 Windows 上只需要一个符号链接。

  2. [Python.Docs]:os.walk(top, topdown=True, onerror=None, followlinks=False)

    • 使用 os.listdir(os.scandir,如果可用)
  3. [Python.Docs]:glob.iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False) (或其前身:glob.glob)

    • 本身似乎不是一个遍历函数(至少在某些情况下),但它仍然使用 os.listdir


由于这些遍历文件夹,(在大多数情况下)它们对于我们的问题效率低下(也有例外,例如非通配符通配符 - 正如@ShadowRanger指出的那样),所以我不会坚持使用它们。更不用说在某些情况下,可能需要对文件名进行处理。

4. [Python.Docs]:os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)

它的行为接近 os.path.exists(实际上它更广泛,主要是因为第 2参数)。

  • 用户权限可能会限制文件的“可见性”,如文档所述:

    ...测试调用用户是否具有对路径的指定访问权限。F_OK mode 来测试路径...

  • 安全注意事项

    使用 access() 检查用户是否被授权,例如,在实际打开文件之前,使用 open() 会创建一个安全漏洞,因为用户可能会利用检查和打开文件之间的短时间间隔来操作它。

os.access("/tmp", os.F_OK)

由于我也使用 C 语言,所以我也使用这种方法,因为在后台,它调用本机 APIs(再次,通过“${PYTHON_SRC_DIR}/Modules/posixmodule.c”),但它也为可能的用户错误打开了大门,并且它不像其他变体那样像 Pythonic。所以,除非你知道你在做什么,否则不要使用它:

如上所述,强烈建议不要使用这种方法(尤其是在 Nix 上)。

注意:也可以通过 [Python.Docs] 调用原生 API s: ctypes - Python 的外部函数库,但在大多数情况下它更复杂。在使用 CTypes 之前,请检查 [SO]:通过 ctypes 从 Python 调用的 C 函数返回不正确的值(@CristiFati的答案)。

(特定于 Win):由于 vcruntime###.dllmsvcr###.dll 对于较旧的 VStudio 版本 - 我将其称为 UCRT)导出 [MS.学习]:_access,_waccess函数系列,下面是一个示例(请注意,推荐的 [Python.Docs]:msvcrt - MS VC++ 运行时中的有用例程不会导出它们):

Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes as cts, os
>>> cts.CDLL("msvcrt")._waccess(u"C:\\Windows\\Temp", os.F_OK)
0
>>> cts.CDLL("msvcrt")._waccess(u"C:\\Windows\\Temp.notexist", os.F_OK)
-1

注意

  • 虽然这不是一个好的做法,但我正在使用 os。F_OK,但这只是为了清楚起见(其值为 0)

  • 我正在使用 _waccess,以便相同的代码适用于 Python 3Python 2(尽管 [维基百科]:它们之间存在 Unicode 相关差异 - [SO]:将 utf-16 字符串传递给 Windows 函数(@CristiFati的答案))

  • 虽然这针对一个非常具体的领域,但在之前的任何答案中都没有提到


LinuxUbuntu[Wikipedia]: Ubuntu version history16 x86_64pc064)) 对应物也是如此:

Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes as cts, os
>>> cts.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
0
>>> cts.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp.notexist", os.F_OK)
-1

注意

  • 取而代之的是,硬编码 libc.soLibC) 的路径 (“/lib/x86_64-linux-gnu/libc.so.6”),该路径可能(并且很可能)因系统而异,None (或空字符串) 可以传递给 CDLL 构造函数 (ctypes.CDLL(None).access(b“/tmp”, os.F_OK))。根据 [Man7]: DLOPEN(3):

    如果 filename 为 NULL,则返回的句柄用于 main 程序。当给定给 dlsym(3) 时, 这个句柄会导致搜索 符号,后跟所有加载的共享对象 程序启动,然后 dlopen() 加载的所有共享对象 旗帜RTLD_GLOBAL

  • 主(当前)程序(python)与LibC链接,因此将加载其符号(包括访问

  • 这必须小心处理,因为 mainPy_Main 和(所有)其他功能都可用;打电话给他们可能会产生灾难性的影响(对当前程序)

  • 这也不适用于 Windows(但这没什么大不了的,因为 UCRT 位于“%SystemRoot%\System32”中,默认情况下位于 %PATH% 中)。我想更进一步,在 Windows 上复制这种行为(并提交补丁),但事实证明,[MS.学习]:GetProcAddress 函数 (libloaderapi.h) 只能“看到”导出的符号,因此除非有人将主可执行文件中的函数声明为(为什么普通人会这样做?),否则主程序是可加载的,但它几乎无法使用__declspec(dllexport)

5. 具有文件系统功能的第三方模块

最有可能的是,将依赖上述方法之一(可能略有自定义)。
一个例子是(再次,特定于 Win)[GitHub]: mhammond/pywin32 - Python for Windows (pywin32) Extensions,它是 WinAPIPython 包装器。

但是,由于这更像是一种解决方法,因此我到此为止。

6. SysAdmin方法

我认为这是一个(蹩脚的)解决方法(gainarie):使用 Python 作为包装器来执行 shell 命令:

  • 赢:

    (py35x64_test) [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q000082831]> "e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\Temp\" > nul 2>&1'))"
    0
    
    (py35x64_test) [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q000082831]> "e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\Temp.notexist\" > nul 2>&1'))"
    1
    
  • Nix[Wikipedia]: 类 Unix) - Ubuntu

    [cfati@cfati-5510-0:/mnt/e/Work/Dev/StackOverflow/q000082831]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))"
    0
    [cfati@cfati-5510-0:/mnt/e/Work/Dev/StackOverflow/q000082831]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))"
    512
    

底线:

  • 请使用 try / except / else / finally 块,因为它们可以防止您遇到一系列令人讨厌的问题

  • 我能想到的一个可能的反例是性能:这样的块很昂贵,所以尽量不要把它们放在每秒应该运行数十万次的代码中(但由于(在大多数情况下)它涉及磁盘访问,所以情况并非如此)

评论

7赞 CristiFati 11/20/2017
@sk8asd123:在评论中很难做到:一般来说,最好将常量与它们结合在一起的函数一起使用。这适用于使用定义相同常量的多个模块,因为有些模块可能不是最新的,并且函数和常量最好保持同步。使用ctypes(直接调用函数)时,我应该定义常量(来自MSDN),或者根本不使用常量。这只是我使用的一个指南,在 99.9% 中它可能没有区别(在功能上)。
4赞 ShadowRanger 11/30/2017
@CristiFati:从 3.6 开始,glob.iglob(以及 glob.glob)都是基于 os.scandir 的,所以它现在是懒惰的;要在包含 10M 个文件的目录中获得第一次命中,您只需扫描直到到达第一个命中。即使在 3.6 之前,如果您使用没有任何通配符的方法,该函数也很聪明:它知道您只能命中一次,因此它将通配简化为仅 os.path.isdir 或 os.path.lexists(取决于路径是否以 结尾)。glob/
4赞 ShadowRanger 11/30/2017
我评论的第二部分(非通配符通配符实际上并没有迭代文件夹,而且从来没有)确实意味着它是解决问题的一个非常有效的解决方案(比直接调用慢,或者因为它是一堆 Python 级别的函数调用和字符串操作,然后它决定有效路径是可行的,但没有额外的系统调用或 I/O 工作, 这慢了几个数量级)。os.path.isdiros.path.lexist
22赞 durjoy 8/10/2017 #32

如果您已经出于其他目的导入了 NumPy,则无需导入其他库,如 、 、 等。pathlibospaths

import numpy as np
np.DataSource().exists("path/to/your/file")

这将根据其存在返回 true 或 false。

56赞 Wizard 12/4/2017 #33

日期: 2017-12-04

其他答案中列出了所有可能的解决方案。

检查文件是否存在的一种直观且有争议的方法是:

import os

os.path.isfile('~/file.md')  # Returns True if exists, else False

# Additionally, check a directory
os.path.isdir('~/folder')  # Returns True if the folder exists, else False

# Check either a directory or a file
os.path.exists('~/file')

我做了一个详尽的备忘单供你参考:

# os.path methods in exhaustive cheat sheet
{'definition': ['dirname',
               'basename',
               'abspath',
               'relpath',
               'commonpath',
               'normpath',
               'realpath'],
'operation': ['split', 'splitdrive', 'splitext',
               'join', 'normcase'],
'compare': ['samefile', 'sameopenfile', 'samestat'],
'condition': ['isdir',
              'isfile',
              'exists',
              'lexists'
              'islink',
              'isabs',
              'ismount',],
 'expand': ['expanduser',
            'expandvars'],
 'stat': ['getatime', 'getctime', 'getmtime',
          'getsize']}
23赞 Ali Hallaji 3/4/2018 #34

检查文件或目录是否存在

您可以按照以下三种方式操作:

1.使用 isfile()

注1:仅用于文件os.path.isfile

import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists

2.使用存在

注 2:用于文件和目录os.path.exists

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) # True if directory exists

3. 方法(包含在 Python 3+ 中,可使用 Python 2 的 pip 安装)pathlib.Path

from pathlib import Path
Path(filename).exists()
6赞 Vimal Maheedharan 10/31/2018 #35

用:

import os

# For testing purposes the arguments defaulted to the current folder and file.
# returns True if file found
def file_exists(FOLDER_PATH='../', FILE_NAME=__file__):
    return os.path.isdir(FOLDER_PATH) \
        and os.path.isfile(os.path.join(FOLDER_PATH, FILE_NAME))

它基本上是文件夹检查,然后使用 os.path.join 使用正确的目录分隔符进行文件检查。

10赞 Gopinath 1/27/2020 #36

'Path' 对象的 exists() 和 is_file() 方法可用于检查给定路径是否存在并且是文件。

Python 3 程序检查文件是否存在:

# File name:  check-if-file-exists.py

from pathlib import Path

filePath = Path(input("Enter path of the file to be found: "))

if filePath.exists() and filePath.is_file():
    print("Success: File exists")
else:
    print("Error: File does not exist")

输出:

$ python3 check-if-file-exists.py

输入要查找的文件的路径:/Users/macuser1/stack-overflow/index.html

成功:文件存在

$ python3 check-if-file-exists.py

输入要找到的文件路径:hghjg jghj

错误:文件不存在

9赞 Devbrat Shukla 5/12/2020 #37

使用 os.path.exists() 检查文件是否存在:

def fileAtLocation(filename,path):
    return os.path.exists(path + filename)
 

filename="dummy.txt"
path = "/home/ie/SachinSaga/scripts/subscription_unit_reader_file/"


if fileAtLocation(filename,path):
   print('file found at location..')
else:
   print('file not found at location..')

评论

0赞 Yash Nag 9/29/2020
关于为什么这个答案被否决的任何澄清?os.path.exists() 不是解决方案吗?
3赞 pho 9/30/2020
@YashNag来自另一个答案:与 不同,将为目录返回 True。isfile()exists()
1赞 Glenn Maynard 2/11/2021
这通常是你想要的,而不是 isfile,因为“文件是否存在”的问题通常是问路径是否存在,而不是它是否是文件。请停止对有用的信息投反对票。
0赞 Ceisc 3/12/2021
为什么要替换文件名中的空格?您现在可以检查是否存在与所询问的文件不同的文件。你为什么要在它上面调用str()?如果它还不是定义文件的字符串,则函数的调用方式可能存在严重错误。
1赞 tdelaney 9/15/2021
@GlennMaynard - 不,您检查文件是否存在,因为您想对文件执行某些操作(也许读取它,也许创建一个)。拥有同名的目录是一个问题。您通常希望对两者进行测试以避免错误。
98赞 Memin 1/23/2021 #38

TL;
DR 答案是:使用 pathlib 模块


Pathlib 可能是几乎所有文件操作最现代、最方便的方式。对于文件文件夹的存在,一行代码就足够了。如果 file 不存在,则不会引发任何异常。

from pathlib import Path

if Path("myfile.txt").exists(): # works for both file and folders
    # do your cool stuff...

该模块是在 Python 3.4 中引入的,因此您需要拥有 Python 3.4+。这个库让你在处理文件和文件夹时的生活更轻松,而且使用起来很漂亮。以下是有关它的更多文档: pathlib — 面向对象的文件系统路径pathlib

顺便说一句,如果您要重用路径,那么最好将其分配给变量。

所以它将变成:

from pathlib import Path

p = Path("loc/of/myfile.txt")
if p.exists(): # works for both file and folders
    # do stuffs...
#reuse 'p' if needed.

评论

7赞 bravhek 6/26/2021
请注意,如果文件不存在但文件路径存在,则返回 True。如果你真的有兴趣询问文件是否存在,你应该使用 p.is_file()
1赞 starriet 3/13/2023
@bravhek我认为你的评论令人困惑。“文件路径”是什么意思?如果你的意思是“目录的路径”,并且目录存在,那么它当然可以正常工作。OP表示适用于文件和文件夹。p.exists()
0赞 Bravhek 3/14/2023
@starriet,问题是关于文件的存在,但是当包含已检查文件的文件夹存在但文件本身不存在时,p.exists() 将返回误报。
0赞 Memin 3/14/2023
@Bravhek,您能否举个例子以更好地突出问题,我也可以相应地更新我的答案,以更好地告知用户。谢谢。
0赞 Bravhek 3/15/2023
@Memin,假设您要检查文件夹“c:\temp”中是否存在文件“myfile.txt”。如果声明 fpath = Path(r“c:\temp\myfile.txt”),然后检查 fpath.exists(),它将返回 True,但文件不存在!(误报)...相反,fpath.is_file() 将返回 false,wich 是所需的输出。
4赞 IsraelW 4/8/2021 #39

另一个可能的选择是使用 os.listdir() 检查文件名是否在目录中:

import os
if 'foo.txt' in os.listdir():
    # Do things

如果是,则返回 true,如果不是,则返回 false。

评论

0赞 Niccolo M. 7/28/2022
如果操作系统不区分大小写,如在MS-Windows中,这可能会失败,因为实际文件名可能是“Foo.TXT”。使用 pathlib 可以解决此问题(因为它使用操作系统约定比较 Path 对象):。if Path('foo.txt') in Path().iterdir()
0赞 Ban_Midou 7/23/2022 #40

这就是我如何在一个文件夹中找到文件列表(在这些图像中)并在文件夹(带有子文件夹)中搜索它:

# This script concatenates JavaScript files into a unified JavaScript file to reduce server round-trips

import os
import string
import math
import ntpath
import sys

#import pyodbc

import gzip
import shutil

import hashlib

# BUF_SIZE is totally arbitrary, change for your app!
BUF_SIZE = 65536  # Let’s read stuff in 64 kilobyte chunks

# Iterate over all JavaScript files in the folder and combine them
filenames = []
shortfilenames = []

imgfilenames = []
imgshortfilenames = []

# Get a unified path so we can stop dancing with user paths.
# Determine where files are on this machine (%TEMP% directory and application installation directory)
if '.exe' in sys.argv[0]: # if getattr(sys, 'frozen', False):
    RootPath = os.path.abspath(os.path.join(__file__, "..\\"))

elif __file__:
    RootPath = os.path.abspath(os.path.join(__file__, "..\\"))

print ("\n storage of image files RootPath: %s\n" %RootPath)

FolderPath = "D:\\TFS-FARM1\\StoneSoup_STS\\SDLC\\Build\\Code\\StoneSoup_Refactor\\StoneSoupUI\\Images"
print ("\n storage of image files in folder to search: %s\n" %FolderPath)

for root, directories, filenames2 in os.walk(FolderPath):
    for filename in filenames2:
        fullname = os.path.join(root, filename)
        filenames.append(fullname)
        shortfilenames.append(filename)

for i, fname in enumerate(shortfilenames):
        print("%s - %s" % (i+1, fname))

for root, directories, filenames2 in os.walk(RootPath):
    for filename in filenames2:
        fullname = os.path.join(root, filename)
        imgfilenames.append(fullname)
        imgshortfilenames.append(filename)

for i, fname in enumerate(imgshortfilenames):
        print("%s - %s" % (i+1, fname))

for i, fname in enumerate(imgshortfilenames):
        if fname in shortfilenames:
            print("%s - %s exists" % (i+1, fname))
        else:
            print("%s - %s ABSENT" % (i+1, fname))