提问



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

最佳参考


如果您正在检查的原因是,您可以执行if file_exists: open_it()之类的操作,那么在尝试打开它时使用try会更安全。检查然后打开风险,删除或移动文件或检查时以及尝试打开文件时。


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



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



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


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


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


from pathlib import Path

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


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


if my_file.is_dir():
    # directory exists


要检查Path对象是否存在,无论它是文件还是目录,请使用exists():


if my_file.exists():
    # path exists


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


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

其它参考1


你有os.path.exists功能:[219]


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


这会为文件和目录返回True,但您可以改为使用


os.path.isfile(file_name)


测试它是否是一个特定的文件。它遵循符号链接。

其它参考2


isfile()不同,exists()将为目录返回True
因此,根据您是否只需要普通文件或目录,您将使用isfile()exists()。这是一个简单的REPL输出。[220] [221]


>>> print os.path.isfile("/etc/password.txt")
True
>>> print os.path.isfile("/etc")
False
>>> print os.path.isfile("/does/not/exist")
False
>>> print os.path.exists("/etc/password.txt")
True
>>> print os.path.exists("/etc")
True
>>> print os.path.exists("/does/not/exist")
False

其它参考3


import os.path

if os.path.isfile(filepath):

其它参考4


os.path.isfile()os.access():[222] [223]一起使用


import os
import os.path

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"

其它参考5


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

其它参考6


这是检查文件是否存在的最简单方法。只需,因为当您检查时,保证文件存在,当您需要打开它时它会存在。


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")

其它参考7


2017/12/22 :


虽然几乎所有可能的方式都已列入(至少有一个)现有答案(例如 Python 3.4 特定内容),但我会尝试将所有内容组合在一起。


注意:我即将发布的每个 Python 标准库代码,属于 3.5.3 版本(doc引用为版本 3 具体)。


问题陈述:



  1. 检查文件(可论证的:也是文件夹(特殊文件)?)存在

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



可能的解决方案:



  1. [[Python]]:os.path。存在(路径)(另请查看其他函数族成员,如os.path.isfileos.path.isdir,[[os.path.lexists略有不同的行为)[224]


    os.path.exists(path)
    



      如果 path 引用现有路径或打开文件描述符,则返回True。对于损坏的符号链接,返回False。在某些平台上,如果未授予对所请求文件执行os.stat()的权限,则此函数可能返回False,即使路径在物理上存在。[225]



    一切都很好,但是如果跟随导入树:



    • os.path - posixpath.py ( ntpath.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]]的try/except块:os。 stat ( path,*,dir_fd=None,follow_symlinks=True )。所以,你的代码try/except是免费的,但在框架中较低,那里(至少)一个这样的块。这也适用于其他功能(包括 os.path.isfile)。[226]


    1.1。 [[Python]]:pathlib.Path。 is_file ()[227]



    • 这是一种处理路径的方式(更多 python ic)

    • 在幕后,它确实完全相同的事情( 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]]:使用语句上下文管理器。任一:[228]



    • 创建一个:


      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)
              return exc_type in Swallow.swallowed_exceptions  # only swallow FileNotFoundError (not e.g. TypeError - if the user passes a wrong argument like None or float or ...)
      



      • 及其用法 - 我会复制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]]:contextlib。抑制( *例外) - 具体旨在有选择地抑制异常[229]



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



      这允许常见的尝试...除了...最终使用模式被封装以便于重用。[231] [232] [233]


  3. 文件系统遍历功能(并搜索匹配项目的结果)



    • [[Python]]:os。 listdir ( path =。)(或[[Python]]:os。 scandir ( 3.5 + )[234] [235]上的> path =。



      • 引擎盖下,都使用[[man]]:OPENDIR(3)/[[man]]:READDIR(3)/[[man]]:CLOSEDIR(3)([[MSDN]]:FindFirstFile函数/[[MSDN]]:FindNextFile函数/[[MSDN]]:FindClose函数) - 通过$ {PYTHON_SRC_DIR}/Modules/posixmodule.c




        使用scandir()而不是listdir()可以显着提高还需要文件类型或文件属性信息的代码的性能,因为os.DirEntry对象在操作系统扫描目录时提供此信息。所有os.DirEntry方法都可以执行系统调用,但is_dir()和is_file()通常只需要对符号链接进行系统调用; os.DirEntry.stat()总是需要在Unix上进行系统调用,但只需要一个用于Windows上的符号链接。[236] [237] [238] [239] [240] [[[241] [242] [243] [244] [245] [246] [247] [248]


    • [[Python]]:os。 walk ( top,topdown=True,onerror=None,followlinks=False )


      • 使用os.listdir(os.scandir可用时)


    • [[Python]]:glob。 iglob ( pathname,recursive=False )([[Python]]:glob。 glob ( pathname,*,recursive=False ))


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





    由于这些迭代文件夹(在大多数情况下)它们对我们的问题效率低(有异常,比如非通配的 glob bing - 正如@ShadowRanger指出的那样),所以我我不会坚持他们。更不用说在某些情况下,可能需要文件名处理。[249] [250] [251]

  4. [[Python]]:os。 access ( path,mode,*,dir_fd=None,effective_ids=False,follow_symlinks=True ),其行为接近于os.path.exists(实际上它更宽,主要是因为2 nd 论证)[252]



    • 用户权限可能会限制文件可见性,因为文档指出:


        ...测试调用用户是否具有 path 的指定访问权限。 模式应为F_OK以测试路径的存在... [253]







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


    由于我也在 C 中工作,我也使用这种方法,因为它引用了原生的 API s (再次,通过$ {PYTHON_SRC_DIR}/Modules/posixmodule.c),但它也为可能的用户错误打开了一扇门,它不像 Python ic作为其他变种。所以,正如@AaronHall正确地指出的那样,除非你知道你在做什么,否则不要使用它:



    • Ux :[[man]]:ACCESS(2)(!!!注意关于安全漏洞的说明其用法可能会介绍!!!)

    • Win :[[MSDN]]:GetFileAttributes函数



    注意:也可以通过[[Python]]调用本机 API : ctypes - 用于Python的外部函数库,但在大多数情况下它更复杂。[254] [255] [256]


    ( Win 特定):由于 msvcr * ( vcruntime * )导出[[MSDN]]:_ access,_waccess函数家庭也是如此,这是一个例子:[257]



    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 os, ctypes
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe", os.F_OK)
    0
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\___cmd.exe", os.F_OK)
    -1
    



    备注:



    • 虽然这不是一个好习惯,但我在通话中使用os.F_OK,但这只是为了清晰(它的值是 0 )

    • 我正在使用_waccess,因此相同的代码适用于 Python3 和 Python2 (尽管 unicode 相关差异他们之间)

    • 虽然这针对的是一个非常具体的区域,以前的任何答案都没有提及




    Lnx ( Ubtu(16 x64))对应物:



    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 os, ctypes
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
    0
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp1", os.F_OK)
    -1
    



    备注:



    • 而不是硬编码 libc 的路径(/lib/x86_64-linux-gnu/libc.so.6),这可能(并且很可能会)不同系统,None(或空字符串)可以传递给CDLL构造函数(ctypes.CDLL(None).access(b"/tmp", os.F_OK)。根据[[man]]:DLOPEN(3):[258]



        如果 filename 为NULL,则返回的句柄用于main
        程序。当赋予 dlsym ()时,此句柄会导致搜索a
        主程序中的符号,后跟加载的所有共享对象
        程序启动,然后由 dlopen ()加载的所有共享对象
        标志 RTLD_GLOBAL




      • 主要(当前)程序( python )与 libc 相关联,因此将加载其符号(包括access)

      • 必须谨慎处理,因为mainPy_Main和(所有)其他功能可用;打电话给他们可能会产生灾难性后果(在当前的节目中)

      • 这也不适用于 Win (但这并不是什么大问题,因为 msvcrt.dll 位于%SystemRoot% \\ System32默认位于%PATH%中)。我想更进一步,并在 Win 上复制此行为(并提交补丁),但事实证明,[[MSDN]]:GetProcAddress函数仅看到导出符号,所以除非有人将主要可执行文件中的函数声明为__declspec(dllexport)(为什么地球上的常规人会这样做?),主程序是可加载的但是几乎无法使用



  5. 使用文件系统功能安装一些3 rd Party模块[259]


    最有可能的,将依赖于上述方法之一(可能需要轻微的自定义)。
    一个例子(再次, Win 特定)[[GitHub]]:Python for Windows(pywin32)扩展,这是 Python 在 WINAPI 上的包装。[260]


    但是,因为这更像是一种解决方法,我会停在这里。

  6. 另一个(蹩脚的)解决方法( gainarie )是(我喜欢称之为) sysadmin 方法:使用 Python 作为包装器执行shell命令



    • :



      (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe\" > nul 2>&1'))"
      0
      
      (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))"
      1
      


    • Lnx ( Ubtu ):



      [cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))"
      0
      [cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))"
      512
      





底线:



  • 执行使用try/except/else/finally阻止,因为它们可以防止您遇到一系列令人讨厌的问题。我能想到的反例是性能:这样的块很昂贵,所以尽量不要将它们放在代码中,它应该每秒运行数十万次(但是因为(在大多数情况下)它涉及磁盘访问,它不会是这样的。



最终说明:



  • 我会尽量保持最新,欢迎提出任何建议,我会将有用的内容纳入到答案中


其它参考8


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


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

其它参考9


喜欢try语句。它被认为是更好的风格,避免了竞争条件。


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



  • 样式:http://allendowney.com/sd/notes/notes11.txt
  • 的处理异常情况部分
  • 避免竞争条件


其它参考10



  

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




现在可以从Python 3.4开始,使用文件名导入和实例化Path对象,并检查is_file方法(请注意,对于指向常规文件的符号链接,这也会返回True):[262]]] [263]


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


如果您使用的是Python 2,则可以从pypi,pathlib2向后端口传输pathlib模块,或者从os.path模块中检查isfile:[264]


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


现在上面可能是这里最好的实用直接答案,但是存在竞争条件的可能性(取决于你想要完成的事情),以及底层实现使用try的事实,但是Python在其实现中无处不在try


因为Python在任何地方使用try,所以没有理由避免使用它的实现。


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


更长,更迂腐的答案



自Python 3.4起可用,使用pathlib中的新Path对象。请注意.exists不太正确,因为目录不是文件(除了在unix意义上所有是文件)。


>>> 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_file使用try:[265]


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


种族条件:为什么我们喜欢尝试



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


如果要在尝试读取文件之前检查文件是否存在,并且可能正在删除它,然后您可能正在使用多个线程或进程,或者其他程序知道该文件并且可能删除它 - 您冒险一个竞争条件,如果你检查它存在,因为你竞赛在条件(它的存在)发生变化之前打开它。


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


但如果这是你的动机,那么可以通过使用suppress上下文管理器来获取try语句的值。


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



Python 3.4为我们提供了suppress上下文管理器(以前的ignore上下文管理器),它在语义上用更少的行完成相同的事情,同时(至少表面上)满足原始的要求以避免[[try声明:[266] [267]


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()
... 
>>> 


对于早期的蟒蛇,你可以自己滚动suppress,但没有try会更加冗长。我相信这实际上是唯一没有在Python 中使用try的答案,可以应用于Python 3.4之前,因为它使用了上下文管理器:


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


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



ISFILE


import os
os.path.isfile(path)


来自文件:[268]



  os.path.isfile(path)

  
  如果path是现有常规文件,则返回True。这符合象征意义
  链接,因此islink()isfile()对于同一路径都可以为真。



但是如果你检查一下这个函数的来源,你会发现它确实使用了一个try语句:[269]



# 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


os.access


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


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


它也遇到与isfile相同的竞争条件问题。来自文件:[270]



  注意:
  使用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。


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


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

其它参考11


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使您可以更轻松地使用操作系统导航和执行标准操作。


有关参考,请参阅如何使用Python检查文件是否存在?/q/82831


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

其它参考12


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


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


[272]


您还可以使用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

其它参考13


看起来似乎在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'


如果你需要文件锁定,这是另一回事。

其它参考14


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():
    ...

其它参考15


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


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]]没有这样的文件或目录:
  whatever.txt)



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

其它参考16


虽然我总是建议使用tryexcept语句,但这里有一些可能性(我个人最喜欢使用os.access):



  1. 尝试打开文件:


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


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


    如果它是假的,它将停止执行unhanded IOError
    或更高版本的Python中的OSError。要抓住异常,
    你必须使用try except子句。当然,你可以随时
    使用try除了`之类的声明(感谢hsandt
    让我思考):


    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文档,输入os.F_OK,它将检查路径是否存在。但是,使用此方法会创建一个安全漏洞,因为有人可以使用检查权限和打开文件之间的时间来攻击您的文件。您应该直接打开文件而不是检查其权限。 (EAFP与LBYP)。如果你以后不打算打开文件,只检查它的存在,那么就可以使用它。[274] [275]


    无论如何,这里:


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



我还要提一下,有两种方法可以验证文件是否存在。问题将是permission deniedno such file or directory。如果你抓到IOError,设置IOError as e(就像我的第一个选项),然后输入print(e.args),这样你就可以确定你的问题了。我希望它有所帮助! :)

其它参考17


另外,os.access():


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


R_OKW_OKX_OK标志来测试权限(doc)。[276]

其它参考18


在Python 3.4中,该语言提供了一个管理文件的新模块:


import pathlib
path = pathlib.Path('path/to/file')
if path.is_file(): # If you want to check a directory: path.is_dir()
    # If it is true, return true on your code.

其它参考19


if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"



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



SRC:http://www.pfinn.net/python-check-if-file-exists.html [277]

其它参考20


你可以在没有try:的情况下写出Brian的建议。


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

其它参考21


这是一个用于Linux命令行环境的1行Python命令。我发现这非常实用,因为我不是那么热门的Bash人。


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


我希望这是有帮助的。

其它参考22


添加一个稍微不同的变化,这个变化并没有完全反映在其他答案中。


这将处理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):

其它参考23


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


代码本身不使用try块...除了确定操作系统,从而引导您进入Unix风格find或手动find。时间测试显示try在确定操作系统时速度更快,所以我确实在那里使用了一个(但没有其他地方)。


>>> 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[278]

其它参考24


检查文件或目录是否存在



您可以遵循以下三种方式:



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



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



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



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



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



from pathlib import Path
Path(filename).exists()

其它参考25


日期:2017年12月4日


其他答案中列出了每种可能的解决方案。


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


import os
os.path.isfile('~/file.md')    # Returns True if exists, else False
additionaly check a dir
os.path.isdir('~/folder') # Returns True if the folder exists, else False
check either a dir or a file
os.path.exists('~/file')


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


#os.path methods in exhaustive cheatsheet
{'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']}

其它参考26


您可以使用Python的OS库:


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

其它参考27



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



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


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


isfile实际上只是一个内部使用os.statstat.S_ISREG(mode)的辅助方法。此os.stat是一种较低级别的方法,它将为您提供有关文件,目录,套接字,缓冲区等的详细信息。关于os.stat的更多信息[279]


注意:但是,此方法不会以任何方式锁定文件,因此您的代码可能会受到检查时间的攻击( TOCTTOU )错误。


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

其它参考28


如果文件用于打开,您可以使用以下技术之一:


>>> with open('somefile', 'xt') as f: #Using the x-flag, Python3.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!')





更新


为了避免混淆并根据我得到的答案,当前答案找到文件具有给定名称的目录。

其它参考29


import os
path = /path/to/dir

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


检查多个文件时这很有用。或者您想要与现有列表进行集合交叉/减法。