如何检查文件是否存在?

时间:2021-12-31 11:45:55

How to see if a file exists or not, without using the try statement?

如何查看是否存在文件,而不使用try语句?

41 个解决方案

#1


3726  

If the reason you're checking is so you can do something like if file_exists: open_it(), it's safer to use a try around the attempt to open it. Checking and then opening risks the file being deleted or moved or something between when you check and when you try to open it.

如果您正在检查的原因是这样的,那么您可以做一些类似于file_exists: open_it()的操作,那么尝试打开它就更安全了。检查并打开文件被删除或移动的风险,或者当你检查的时候和你试图打开它的时候。

If you're not planning to open the file immediately, you can use os.path.isfile

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

Return True if path is an existing regular file. This follows symbolic links, so both islink() and isfile() can be true for the same path.

如果路径是现有的常规文件,则返回True。这将遵循符号链接,因此islink()和isfile()都适用于相同的路径。

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

if you need to be sure it's a file.

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

Starting with Python 3.4, the pathlib module offers an object-oriented approach (backported to pathlib2 in Python 2.7):

从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

To check a directory, do:

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

if my_file.is_dir():
    # directory exists

To check whether a Path object exists independently of whether is it a file or directory, use exists():

为了检查路径对象是否独立于文件或目录是否存在,使用exists():

if my_file.exists():
    # path exists

You can also use resolve() in a try block:

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

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

#2


1504  

You have the os.path.exists function:

你有os.path。存在功能:

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

This returns True for both files and directories but you can instead use os.path.isfile to test if it's a file specifically. It follows symlinks.

这对于文件和目录都是正确的,但是您可以使用os.path。要测试它是否是一个文件。它遵循符号链接。

#3


819  

Unlike isfile(), exists() will return True for directories.
So depending on if you want only plain files or also directories, you'll use isfile() or exists(). Here is a simple REPL output.

与isfile()不同,exists()将返回对目录的True。因此,如果您只需要普通文件或目录,您将使用isfile()或exists()。这是一个简单的REPL输出。

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

#4


433  

import os.path

if os.path.isfile(filepath):

#5


204  

Use os.path.isfile() with os.access():

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

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 file is missing or is not readable"

#6


185  

import os
os.path.exists(path) # returns whether the path (dir or file) exists or not
os.path.isfile(path) # returns whether the file exists or not

#7


130  

This is the simplest way to check if a file exists. Just because the file existed when you checked doesn't guarantee that it will be there when you need to open it.

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

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

#8


115  

Python 3.4+ has an object-oriented path module: pathlib. Using this new module, you can check whether a file exists like this:

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

You can (and usually should) still use a try/except block when opening files:

你可以(通常应该)在打开文件时仍然使用try/除去块:

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

The pathlib module has lots of cool stuff in it: convenient globbing, checking file's owner, easier path joining, etc. It's worth checking out. If you're on an older Python (version 2.6 or later), you can still install pathlib with pip:

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

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

Then import it as follows:

然后导入如下:

# Older Python versions
import pathlib2 as pathlib

#9


108  

Prefer the try statement. It's considered better style and avoids race conditions.

喜欢尝试的声明。它被认为是更好的风格,避免了比赛条件。

Don't take my word for it. There's plenty of support for this theory. Here's a couple:

不要相信我的话。对这个理论有很多支持。这里有几个:

#10


104  

2017 / 12 / 22:

2017 / 12 / 22:

Although almost every possible way has been listed in (at least one of) the existing answers (e.g. Python 3.4 specific stuff was added), I'll try to group everything together.

尽管几乎所有可能的方法都被列在了(至少是一个)现有的答案中(例如,Python 3.4的具体内容),但我将尝试将所有内容组合在一起。

Note: every piece of Python standard library code that I'm going to post, belongs to version 3.5.3 (doc quotes are version 3 specific).

注意:我将要发布的每一个Python标准库代码都属于版本3.5.3 (doc引用是版本3的特定版本)。

Problem statement:

问题陈述:

  1. Check file (arguable: also folder ("special" file) ?) existence
  2. 检查文件(可论证:文件夹(“特殊”文件)?)存在。
  3. Don't use try / except / else / finally blocks
  4. 不要使用try / else / finally块。

Possible solutions:

可能的解决方式:

  1. [Python]: os.path.exists(path) (also check other function family members like os.path.isfile, os.path.isdir, os.path.lexists for slightly different behaviors)

    存在(路径)(也检查其他功能家庭成员,如os.path)。isfile os.path。isdir os.path。对轻微不同行为的lexists)

    os.path.exists(path)
    

    Return True if path refers to an existing path or an open file descriptor. Returns False for broken symbolic links. On some platforms, this function may return False if permission is not granted to execute os.stat() on the requested file, even if the path physically exists.

    返回True,如果path引用了现有路径或打开的文件描述符。返回False用于中断符号链接。在某些平台上,如果不允许在请求的文件上执行os.stat(),该函数可能返回False,即使该路径在物理上存在。

    All good, but if following the import tree:

    一切都好,但如果遵循进口树:

    • os.path - posixpath.py (ntpath.py)

      操作系统。路径- posixpath。py(ntpath.py)

      • genericpath.py, line ~#20+

        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
        

    it's just a try/except block around [Python]: os.stat(path, *, dir_fd=None, follow_symlinks=True). So, your code is try/except free, but lower in the framestack there's (at least) one such block. This also applies to other funcs (including os.path.isfile).

    它只是一个尝试/除去(Python): os。stat(路径、* dir_fd = None,follow_symlinks = True)。所以,您的代码尝试/除了免费,但是在framestack中更低(至少)有一个这样的块。这也适用于其他函数(包括os.path.isfile)。

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

    1.1。(Python):pathlib.Path.is_file()

    • It's a fancier (and more pythonic) way of handling paths, but
    • 这是一个更好的处理路径的方法,但是。
    • Under the hood, it does exactly the same thing (pathlib.py, line ~#1330):

      在引擎盖下,它做了完全相同的事情(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]: With Statement Context Managers. Either:

    (Python):使用语句上下文管理器。:

    • Create one:

      创建一个:

      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 ...)
      
      • And its usage - I'll replicate the isfile behavior (note that this is just for demonstrating purposes, do not attempt to write such code for production):

        它的用法——我将复制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
        
    • Use [Python]: contextlib.suppress(*exceptions) - which was specifically designed for selectively suppressing exceptions

      使用[Python]: contextlib.抑制(*exception)——它是专门为有选择地抑制异常而设计的。


    But, they seem to be wrappers over try/except/else/finally blocks, as [Python]: The with statement states:

    但是,它们似乎是在尝试/其他/最终块,如[Python]: with语句状态:

    This allows common try...except...finally usage patterns to be encapsulated for convenient reuse.

    这允许共同尝试…除了…最后,将使用模式封装以方便重用。

  3. Filesystem traversal functions (and search the results for matching item(s))

    文件系统遍历函数(并搜索匹配项的结果)

    • [Python]: os.listdir(path='.') (or [Python]: os.scandir(path='.') on Python v3.5+)

      [Python]: os.listdir(path='.)(或[Python]: os.scandir(path='.)在Python v3.5+上)

      Using scandir() instead of listdir() can significantly increase the performance of code that also needs file type or file attribute information, because os.DirEntry objects expose this information if the operating system provides it when scanning a directory. All os.DirEntry methods may perform a system call, but is_dir() and is_file() usually only require a system call for symbolic links; os.DirEntry.stat() always requires a system call on Unix but only requires one for symbolic links on Windows.

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

    • [Python]: os.walk(top, topdown=True, onerror=None, followlinks=False)
      • It uses os.listdir (os.scandir when available)
      • 它使用的操作系统。listdir(操作系统。scandir时可用)
    • (Python):操作系统。walk(top, topdown=True, onerror=None, followlinks=False)使用操作系统。listdir(操作系统。scandir时可用)
    • [Python]: glob.iglob(pathname, recursive=False) ([Python]: glob.glob(pathname, *, recursive=False))
      • Doesn't seem a traversing function per se (at least in some cases), but it still uses os.listdir
      • 它本身并不是一个遍历函数(至少在某些情况下是这样),但是它仍然使用os.listdir。
    • (Python):水珠。iglob(路径名,递归= False)((Python):水珠。glob(路径名,*,递归=False))看起来不是一个遍历函数(至少在某些情况下是这样),但是它仍然使用os.listdir。


    Since these iterate over folders, (in most of the cases) they are inefficient for our problem (there are exceptions, like non wildcarded globbing - as @ShadowRanger pointed out), so I'm not going to insist on them. Not to mention that in some cases, filename processing might be required.

    由于这些迭代遍历了文件夹,(在大多数情况下)它们对我们的问题是低效的(有一些例外,比如不通配符的globbing),所以我不打算坚持它们。更不用说在某些情况下,可能需要文件名处理。

  4. [Python]: os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True) whose behavior is close to os.path.exists (actually it's wider, mainly because of the 2nd argument)

    (Python):操作系统。访问(路径,模式,*,dir_fd=None,有效的id =False, follow_symlinks=True),其行为接近于os.path。存在(实际上它更宽,主要是因为第二个参数)

    • user permissions might restrict the file "visibility" as the doc states:

      ...test if the invoking user has the specified access to path. mode should be F_OK to test the existence of path...

      …测试调用的用户是否具有指定的路径访问权限。模式应该是F_OK来测试路径的存在…

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

    Since I also work in C, I use this method as well because under the hood, it calls native APIs (again, via "${PYTHON_SRC_DIR}/Modules/posixmodule.c"), but it also opens a gate for possible user errors, and it's not as Pythonic as other variants. So, as @AaronHall rightly pointed out, don't use it unless you know what you're doing:

    因为我也在C中工作,所以我也使用这个方法,因为在hood中,它调用native api(同样,通过“${PYTHON_SRC_DIR}/Modules/posixmodule.c”),但是它也为可能的用户错误打开了一个门,它不像其他变体那样是python的。因此,正如@AaronHall正确指出的,除非你知道你在做什么,否则不要使用它:

    • Ux: [man]: ACCESS(2) (!!! pay attention to the note about the security hole its usage might introduce !!!)
    • 用户体验:[人]:访问(2)(! ! !注意安全漏洞的注意,它的使用可能会介绍!!!
    • Win: [MSDN]: GetFileAttributes function
    • 赢得(MSDN)::GetFileAttributes函数

    Note: calling native APIs is also possible via [Python]: ctypes — A foreign function library for Python, but in most cases it's more complicated.

    注意:调用本地api也是可能的,通过[Python]: ctypes——Python的一个外国函数库,但在大多数情况下,它更复杂。

    (Win specific): Since msvcr*(vcruntime*) exports a [MSDN]: _access, _waccess function family as well, here's an example:

    (Win specific):由于msvcr*(vcruntime*)导出了一个[MSDN]: _access, _waccess函数家族,这里有一个例子:

    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
    

    Notes:

    注:

    • Although it's not a good practice, I'm using os.F_OK in the call, but that's just for clarity (its value is 0)
    • 虽然这不是一个好的实践,但我使用的是操作系统。在调用中F_OK,但这只是为了清楚(它的值为0)
    • I'm using _waccess so that the same code works on Python3 and Python2 (in spite of unicode related differences between them)
    • 我使用的是_waccess,以便在Python3和Python2上使用相同的代码(尽管它们之间有unicode相关的差异)
    • Although this targets a very specific area, it was not mentioned in any of the previous answers
    • 虽然这个目标是一个非常具体的领域,但在之前的任何一个答案中都没有提及。


    The Lnx (Ubtu (16 x64)) counterpart as well:

    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
    

    Notes:

    注:

    • Instead hardcoding libc's path ("/lib/x86_64-linux-gnu/libc.so.6") which may (and most likely, will) vary across systems, None (or the empty string) can be passed to CDLL constructor (ctypes.CDLL(None).access(b"/tmp", os.F_OK)). According to [man]: DLOPEN(3):

      相反,硬编码libc的路径(“/lib/x86_64-linux-gnu/libc.so.6”)可能(而且很可能会)在不同的系统中不同,没有(或者空字符串)可以传递给CDLL构造函数(ctypes.CDLL(None)。访问(b“/ tmp”,os.F_OK))。根据[人]:DLOPEN(3):

      If filename is NULL, then the returned handle is for the main program. When given to dlsym(), this handle causes a search for a symbol in the main program, followed by all shared objects loaded at program startup, and then all shared objects loaded by dlopen() with the flag RTLD_GLOBAL.

      如果文件名是NULL,那么返回的句柄是主程序。当给dlsym()时,这个句柄会在主程序中搜索一个符号,然后在程序启动时加载所有共享的对象,然后用RTLD_GLOBAL标记dlopen()加载的所有共享对象。

      • Main (current) program (python) is linked against libc, so its symbols (including access) will be loaded
      • Main (current)程序(python)与libc链接,因此它的符号(包括访问)将被加载。
      • This has to be handled with care, since functions like main, Py_Main and (all the) others are available; calling them could have disastrous effects (on the current program)
      • 这必须小心处理,因为像main、Py_Main和(所有)其他功能都可用;调用它们可能会带来灾难性的影响(在当前的程序中)
      • This doesn't also apply to Win (but that's not such a big deal, since msvcrt.dll is located in "%SystemRoot%\System32" which is in %PATH% by default). I wanted to take things further and replicate this behavior on Win (and submit a patch), but as it turns out, [MSDN]: GetProcAddress function only "sees" exported symbols, so unless someone declares the functions in the main executable as __declspec(dllexport) (why on Earth the regular person would do that?), the main program is loadable but pretty much unusable
      • 这并不适用于Win(但这并不是什么大问题,因为msvcrt)。dll位于“% systemroot% \System32”中,默认情况下是%PATH%。我想进一步和复制这种行为赢得(并提交补丁),但事实证明,[MSDN]:GetProcAddress函数只“看到”导出的符号,所以除非有人宣称的功能主要可执行文件使用__declspec(dllexport)(为什么在地球上正常的人会这么做?),主程序可加载,但几乎无法使用
  5. Install some 3rd Party module with filesystem capabilities

    使用文件系统功能安装一些第三方模块。

    Most likely, will rely on one of the ways above (maybe with slight customizations).
    One example would be (again, Win specific) [GitHub]: Python for Windows (pywin32) Extensions, which is a Python wrapper over WINAPIs.

    最有可能的是,它将依赖于上面的一种方法(可能有轻微的自定义)。一个例子是(再次,赢得特定的)[GitHub]:用于Windows的Python (pywin32)扩展,它是针对winapi的Python包装器。

    But, since this is more like a workaround, I'm stopping here.

    但是,既然这更像是一个变通方法,我就停在这里。

  6. Another (lame) workaround (gainarie) is (as I like to call it,) the sysadmin approach: use Python as a wrapper to execute shell commands

    另一个(笨拙的)解决方案(我喜欢这样称呼它):sysadmin方法:使用Python作为执行shell命令的包装器。

    • Win:

      赢得:

      (py35x64_test) e:\Work\Dev\*\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\*\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):

      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
      

Bottom line:

底线:

  • Do use try / except / else / finally blocks, because they can prevent you running into a series of nasty problems. A counter-example that I can think of, is performance: such blocks are costly, so try not to place them in code that it's supposed to run hundreds of thousands times per second (but since (in most cases) it involves disk access, it won't be the case).
  • 使用try / except / else / finally块,因为它们可以防止你遇到一系列严重的问题。我可以想到的一个反例是性能:这些块非常昂贵,所以尽量不要把它们放在代码中,它应该每秒运行数十万次(但是因为(在大多数情况下)它涉及到磁盘访问,它不会是这样的情况)。

Final note(s):

最后注意(s):

  • I will try to keep it up to date, any suggestions are welcome, I will incorporate anything useful that will come up into the answer
  • 我会尽量保持最新的,任何建议都是欢迎的,我会把任何有用的东西加入到答案中。

#11


89  

How do I check whether a file exists, using Python, without using a try statement?

Now available since Python 3.4, import and instantiate a Path object with the file name, and check the is_file method (note that this returns True for symlinks pointing to regular files as well):

现在,从Python 3.4开始,导入并实例化一个带有文件名的路径对象,并检查is_file方法(注意,这个返回的结果对于指向普通文件的符号链接也是正确的):

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

If you're on Python 2, you can backport the pathlib module from pypi, pathlib2, or otherwise check isfile from the os.path module:

如果您使用的是python2,您可以从pypi、pathlib2或从操作系统中检查isfile来支持pathlib模块。路径模块:

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

Now the above is probably the best pragmatic direct answer here, but there's the possibility of a race condition (depending on what you're trying to accomplish), and the fact that the underlying implementation uses a try, but Python uses try everywhere in its implementation.

现在,上面可能是最实用的直接回答,但是有可能出现竞态条件(取决于您要完成的任务),以及底层实现使用了一个尝试,但是Python在实现中到处尝试。

Because Python uses try everywhere, there's really no reason to avoid an implementation that uses it.

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

But the rest of this answer attempts to consider these caveats.

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

Longer, much more pedantic answer

Available since Python 3.4, use the new Path object in pathlib. Note that .exists is not quite right, because directories are not files (except in the unix sense that everything is a file).

从Python 3.4开始,在pathlib中使用新的Path对象。注意,存在并不完全正确,因为目录不是文件(除非在unix中,所有东西都是文件)。

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

So we need to use is_file:

所以我们需要使用is_file:

>>> root.is_file()
False

Here's the help on is_file:

下面是is_file的帮助:

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

So let's get a file that we know is a file:

让我们得到一个文件,我们知道它是一个文件

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

By default, NamedTemporaryFile deletes the file when closed (and will automatically close when no more references exist to it).

默认情况下,NamedTemporaryFile在关闭时删除文件(当没有更多引用时,它将自动关闭)。

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

If you dig into the implementation, though, you'll see that is_file uses try:

但是,如果深入到实现中,您将看到is_file使用了try:

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

Race Conditions: Why we like try

We like try because it avoids race conditions. With try, you simply attempt to read your file, expecting it to be there, and if not, you catch the exception and perform whatever fallback behavior makes sense.

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

If you want to check that a file exists before you attempt to read it, and you might be deleting it and then you might be using multiple threads or processes, or another program knows about that file and could delete it - you risk the chance of a race condition if you check it exists, because you are then racing to open it before its condition (its existence) changes.

如果你想检查一个文件是否存在在你试图读它之前,你可能会删除它,然后你可能会使用多个线程或进程,或另一个程序知道该文件,可以删除它——你风险的机会竞争条件如果你检查它的存在,因为你是那么急于打开它之前条件(存在)的变化。

Race conditions are very hard to debug because there's a very small window in which they can cause your program to fail.

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

But if this is your motivation, you can get the value of a try statement by using the suppress context manager.

但是,如果这是您的动机,您可以使用抑制上下文管理器来获得try语句的值。

Avoiding race conditions without a try statement: suppress

Python 3.4 gives us the suppress context manager (previously the ignore context manager), which does semantically exactly the same thing in fewer lines, while also (at least superficially) meeting the original ask to avoid a try statement:

Python 3.4为我们提供了抑制上下文管理器(以前是忽略上下文管理器),它在语义上完全相同,在更少的行中,同时(至少在表面上)满足原始请求,以避免尝试语句:

from contextlib import suppress
from pathlib import Path

Usage:

用法:

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

For earlier Pythons, you could roll your own suppress, but without a try will be more verbose than with. I do believe this actually is the only answer that doesn't use try at any level in the Python that can be applied to prior to Python 3.4 because it uses a context manager instead:

对于较早的python,您可以自己滚动自己的抑制,但是没有尝试将会比使用更冗长。我相信这实际上是唯一一个不使用Python中任何级别的尝试的答案,因为它使用了上下文管理器来代替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)

Perhaps easier with a try:

或许尝试一下更容易:

from contextlib import contextmanager

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

Other options that don't meet the ask for "without try":

isfile

isfile

import os
os.path.isfile(path)

from the docs:

从文档:

os.path.isfile(path)

os.path.isfile(路径)

Return True if path is an existing regular file. This follows symbolic links, so both islink() and isfile() can be true for the same path.

如果路径是现有的常规文件,则返回True。这将遵循符号链接,因此islink()和isfile()都适用于相同的路径。

But if you examine the source of this function, you'll see it actually does use a try statement:

但是如果你检查这个函数的源,你会发现它确实使用了一个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

All it's doing is using the given path to see if it can get stats on it, catching OSError and then checking if it's a file if it didn't raise the exception.

它所做的就是使用给定的路径来查看它是否可以获得数据,捕获OSError,然后检查它是否是一个文件,如果它没有引发异常。

If you intend to do something with the file, I would suggest directly attempting it with a try-except to avoid a race condition:

如果您打算对该文件做一些事情,我建议您直接尝试,除非是为了避免竞态条件:

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

os.access

os.access

Available for Unix and Windows is os.access, but to use you must pass flags, and it does not differentiate between files and directories. This is more used to test if the real invoking user has access in an elevated privilege environment:

Unix和Windows的可用操作系统是os。访问,但是要使用您必须传递标志,并且它不区分文件和目录。这更用于测试实际调用用户是否具有较高的特权环境中的访问权限:

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

It also suffers from the same race condition problems as isfile. From the docs:

它也有与isfile相同的竞争条件问题。从文档:

Note: Using access() to check if a user is authorized to e.g. open a file before actually doing so using open() creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it. It’s preferable to use EAFP techniques. For example:

注意:使用access()来检查用户是否有权在实际使用open()之前打开文件,从而创建一个安全漏洞,因为用户可能会利用检查和打开文件之间的短时间间隔来操作它。最好使用EAFP技术。例如:

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

is better written as:

是更好的写为:

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

Avoid using os.access. It is a low level function that has more opportunities for user error than the higher level objects and functions discussed above.

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

Criticism of another answer:

Another answer says this about os.access:

另一个答案是关于os的。

Personally, I prefer this one because under the hood, it calls native APIs (via "${PYTHON_SRC_DIR}/Modules/posixmodule.c"), but it also opens a gate for possible user errors, and it's not as Pythonic as other variants:

就我个人而言,我更喜欢这一种,因为在它的底层,它调用本地api(通过“${PYTHON_SRC_DIR}/模块/posixmodule.c”),但是它也为可能的用户错误打开了一个门,它不像其他变体那样是python的:

This answer says it prefers a non-Pythonic, error-prone method, with no justification. It seems to encourage users to use low-level APIs without understanding them.

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

It also creates a context manager which, by unconditionally returning True, allows all Exceptions (including KeyboardInterrupt and SystemExit!) to pass silently, which is a good way to hide bugs.

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

This seems to encourage users to adopt poor practices.

这似乎鼓励用户采用糟糕的实践。

#12


73  

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

Importing os makes it easier to navigate and perform standard actions with your operating system.

导入操作系统使操作系统更容易导航和执行标准操作。

For reference also see How to check whether a file exists using Python?

对于引用,还可以查看如何检查是否存在使用Python的文件?

If you need high-level operations, use shutil.

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

#13


61  

Testing for files and folders with os.path.isfile(), os.path.isdir() and os.path.exists()

测试文件和文件夹与os.path.isfile()、os.path.isdir()和os.path.exists()

Assuming that the "path" is a valid path, this table shows what is returned by each function for files and folders:

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

如何检查文件是否存在?

You can also test if a file is a certain type of file using os.path.splitext() to get the extension (if you don't already know it)

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

#14


55  

It doesn't seem like there's a meaningful functional difference between try/except and isfile(), so you should use which one makes sense.

在try/except和isfile()之间似乎不存在有意义的功能差异,所以您应该使用哪一个是有意义的。

If you want to read a file, if it exists, do

如果您想要读取一个文件,如果它存在,请执行。

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

But if you just wanted to rename a file if it exists, and therefore don't need to open it, do

但是,如果您只是想重命名一个文件,如果它存在,因此不需要打开它,那么做。

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

If you want to write to a file, if it doesn't exist, do

如果您想要写入一个文件,如果它不存在,请执行。

# 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'

If you need file locking, that's a different matter.

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

#15


55  

In 2016 the best way is still using os.path.isfile:

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

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

Or in Python 3 you can use pathlib:

或者在python3里你可以使用pathlib:

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

#16


48  

You could try this (safer):

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

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

The ouput would be:

的输出是:

([Errno 2] No such file or directory: 'whatever.txt')

([Errno 2]没有这样的文件或目录:“whatever.txt”)

Then, depending on the result, your program can just keep running from there or you can code to stop it if you want.

然后,根据结果,您的程序可以继续运行,或者您可以编写代码来阻止它。

#17


43  

Although I always recommend using try and except statements, here are a few possibilities for you (my personal favourite is using os.access):

虽然我总是推荐使用try和except,但这里有一些可能性(我个人最喜欢使用os.access):

  1. Try opening the file:

    试着打开文件:

    Opening the file will always verify the existence of the file. You can make a function just like so:

    打开文件将始终验证文件的存在。你可以这样做:

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

    If it's False, it will stop execution with an unhanded IOError or OSError in later versions of Python. To catch the exception, you have to use a try except clause. Of course, you can always use a try except` statement like so (thanks to hsandt for making me think):

    如果它是错误的,那么它将在Python的后续版本中以一个未提交的IOError或OSError停止执行。要捕获异常,您必须使用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. Use os.path.exists(path):

    使用os.path.exists(路径):

    This will check the existence of what you specify. However, it checks for files and directories so beware about how you use it.

    这将检查您指定的内容是否存在。但是,它检查文件和目录,所以要小心使用它。

    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. Use os.access(path, mode):

    使用操作系统。访问(路径、模式):

    This will check whether you have access to the file. It will check for permissions. Based on the os.py documentation, typing in os.F_OK, it will check the existence of the path. However, using this will create a security hole, as someone can attack your file using the time between checking the permissions and opening the file. You should instead go directly to opening the file instead of checking its permissions. (EAFP vs LBYP). If you're not going to open the file afterwards, and only checking its existence, then you can use this.

    这将检查您是否能够访问该文件。它将检查权限。基于操作系统。py文档,在操作系统中输入。F_OK,它将检查路径的存在。但是,使用此方法将创建一个安全漏洞,因为有人可以在检查权限和打开文件之间使用时间来攻击您的文件。相反,您应该直接打开文件,而不是检查其权限。(EAFP vs LBYP)。如果您以后不打算打开文件,并且只检查它的存在,那么您可以使用它。

    Anyway, here:

    不管怎样,在这里:

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

I should also mention that there are two ways that you will not be able to verify the existence of a file. Either the issue will be permission denied or no such file or directory. If you catch an IOError, set the IOError as e (like my first option), and then type in print(e.args) so that you can hopefully determine your issue. I hope it helps! :)

我还应该提到,有两种方法无法验证文件的存在。这个问题将被拒绝,或者没有这个文件或目录。如果您捕获了一个IOError,将IOError设置为e(像我的第一个选项一样),然后输入print(.args),这样您就可以希望确定您的问题了。我希望它可以帮助!:)

#18


31  

Additionally, os.access():

此外,os.access():

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

Being R_OK, W_OK, and X_OK the flags to test for permissions (doc).

使用R_OK、W_OK和X_OK标记来测试权限(doc)。

#19


31  

In Python 3.4 the language provides a new module to manage files:

在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.

#20


18  

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

Raising exceptions is considered to be an acceptable, and Pythonic, approach for flow control in your program. Consider handling missing files with IOErrors. In this situation, an IOError exception will be raised if the file exists but the user does not have read permissions.

在您的程序中,提高异常被认为是一种可接受的、和python的方法。考虑使用IOErrors处理丢失的文件。在这种情况下,如果文件存在,则会引发IOError异常,但用户没有读权限。

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

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

#21


16  

You can write Brian's suggestion without the try:.

你可以不用试着写布莱恩的建议:。

from contextlib import suppress

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

suppress is part of Python 3.4. In older releases you can quickly write your own suppress:

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

from contextlib import contextmanager

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

#22


15  

Here's a 1 line Python command for the Linux command line environment. I find this VERY HANDY since I'm not such a hot Bash guy.

这里是一个用于Linux命令行环境的1行Python命令。我觉得这很方便,因为我不是一个很热情的家伙。

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

I hope this is helpful.

我希望这是有帮助的。

#23


15  

Adding one more slight variation which isn't exactly reflected in the other answers.

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

This will handle the case of the file_path being None or empty string.

这将处理file_path为None或空字符串的情况。

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

Adding a variant based on suggestion from Shahbaz

根据Shahbaz的建议添加一个变体。

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

Adding a variant based on suggestion from Peter Wood

根据Peter Wood的建议添加一个变体。

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

#24


14  

I'm the author of a package that's been around for about 10 years, and it has a function that addresses this question directly. Basically, if you are on a non-Windows system, it uses Popen to access find. However, if you are on Windows, it replicates find with an efficient filesystem walker.

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

The code itself does not use a try block… except in determining the operating system and thus steering you to the "Unix"-style find or the hand-buillt find. Timing tests showed that the try was faster in determining the OS, so I did use one there (but nowhere else).

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

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

And the doc…

和医生……

>>> 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']

>>>

The implementation, if you care to look, is here: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190

如果你想看的话,它的实现是:https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190。

#25


12  

Date:2017-12-04

日期:2017-12-04

Every possible solution has been listed in other answers.

所有可能的解决方案都列在其他答案中。

An intuitive and arguable way to check if a file exists is the following:

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

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

I made an exhaustive cheatsheet for your reference:

我做了一个详尽的备查表,供你参考:

#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


11  

You can use the "OS" library of Python:

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

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

#27


11  

How do I check whether a file exists, without using the try statement?

我如何检查文件是否存在,而不使用try语句?

In 2016, this is still arguably the easiest way to check if both a file exists and if it is a file:

在2016年,这仍然可以说是检查文件是否存在的最简单方法,如果它是一个文件:

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

isfile is actually just a helper method that internally uses os.stat and stat.S_ISREG(mode) underneath. This os.stat is a lower-level method that will provide you with detailed information about files, directories, sockets, buffers, and more. More about os.stat here

isfile实际上只是一个内部使用操作系统的辅助方法。统计和stat.S_ISREG(模式)。这个操作系统。stat是一种较低级别的方法,它将为您提供关于文件、目录、套接字、缓冲区等的详细信息。更多关于操作系统。统计在这里

Note: However, this approach will not lock the file in any way and therefore your code can become vulnerable to "time of check to time of use" (TOCTTOU) bugs.

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

So raising exceptions is considered to be an acceptable, and Pythonic, approach for flow control in your program. And one should consider handling missing files with IOErrors, rather than if statements (just an advice).

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

#28


10  

import os
path = /path/to/dir

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

This is helpful when checking for several files. Or you want to do a set intersection/ subtraction with an existing list.

这在检查几个文件时很有用。或者你想用一个已有的列表来做一个集的交集/减法。

#29


10  

You can use the following open method to check if a file exists + readable:

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

open(inputFile, 'r')

#30


9  

If the file is for opening you could use one of the following techniques:

如果文件是开放的,您可以使用以下技术之一:

>>> 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!')

#1


3726  

If the reason you're checking is so you can do something like if file_exists: open_it(), it's safer to use a try around the attempt to open it. Checking and then opening risks the file being deleted or moved or something between when you check and when you try to open it.

如果您正在检查的原因是这样的,那么您可以做一些类似于file_exists: open_it()的操作,那么尝试打开它就更安全了。检查并打开文件被删除或移动的风险,或者当你检查的时候和你试图打开它的时候。

If you're not planning to open the file immediately, you can use os.path.isfile

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

Return True if path is an existing regular file. This follows symbolic links, so both islink() and isfile() can be true for the same path.

如果路径是现有的常规文件,则返回True。这将遵循符号链接,因此islink()和isfile()都适用于相同的路径。

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

if you need to be sure it's a file.

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

Starting with Python 3.4, the pathlib module offers an object-oriented approach (backported to pathlib2 in Python 2.7):

从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

To check a directory, do:

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

if my_file.is_dir():
    # directory exists

To check whether a Path object exists independently of whether is it a file or directory, use exists():

为了检查路径对象是否独立于文件或目录是否存在,使用exists():

if my_file.exists():
    # path exists

You can also use resolve() in a try block:

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

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

#2


1504  

You have the os.path.exists function:

你有os.path。存在功能:

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

This returns True for both files and directories but you can instead use os.path.isfile to test if it's a file specifically. It follows symlinks.

这对于文件和目录都是正确的,但是您可以使用os.path。要测试它是否是一个文件。它遵循符号链接。

#3


819  

Unlike isfile(), exists() will return True for directories.
So depending on if you want only plain files or also directories, you'll use isfile() or exists(). Here is a simple REPL output.

与isfile()不同,exists()将返回对目录的True。因此,如果您只需要普通文件或目录,您将使用isfile()或exists()。这是一个简单的REPL输出。

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

#4


433  

import os.path

if os.path.isfile(filepath):

#5


204  

Use os.path.isfile() with os.access():

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

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 file is missing or is not readable"

#6


185  

import os
os.path.exists(path) # returns whether the path (dir or file) exists or not
os.path.isfile(path) # returns whether the file exists or not

#7


130  

This is the simplest way to check if a file exists. Just because the file existed when you checked doesn't guarantee that it will be there when you need to open it.

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

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

#8


115  

Python 3.4+ has an object-oriented path module: pathlib. Using this new module, you can check whether a file exists like this:

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

You can (and usually should) still use a try/except block when opening files:

你可以(通常应该)在打开文件时仍然使用try/除去块:

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

The pathlib module has lots of cool stuff in it: convenient globbing, checking file's owner, easier path joining, etc. It's worth checking out. If you're on an older Python (version 2.6 or later), you can still install pathlib with pip:

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

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

Then import it as follows:

然后导入如下:

# Older Python versions
import pathlib2 as pathlib

#9


108  

Prefer the try statement. It's considered better style and avoids race conditions.

喜欢尝试的声明。它被认为是更好的风格,避免了比赛条件。

Don't take my word for it. There's plenty of support for this theory. Here's a couple:

不要相信我的话。对这个理论有很多支持。这里有几个:

#10


104  

2017 / 12 / 22:

2017 / 12 / 22:

Although almost every possible way has been listed in (at least one of) the existing answers (e.g. Python 3.4 specific stuff was added), I'll try to group everything together.

尽管几乎所有可能的方法都被列在了(至少是一个)现有的答案中(例如,Python 3.4的具体内容),但我将尝试将所有内容组合在一起。

Note: every piece of Python standard library code that I'm going to post, belongs to version 3.5.3 (doc quotes are version 3 specific).

注意:我将要发布的每一个Python标准库代码都属于版本3.5.3 (doc引用是版本3的特定版本)。

Problem statement:

问题陈述:

  1. Check file (arguable: also folder ("special" file) ?) existence
  2. 检查文件(可论证:文件夹(“特殊”文件)?)存在。
  3. Don't use try / except / else / finally blocks
  4. 不要使用try / else / finally块。

Possible solutions:

可能的解决方式:

  1. [Python]: os.path.exists(path) (also check other function family members like os.path.isfile, os.path.isdir, os.path.lexists for slightly different behaviors)

    存在(路径)(也检查其他功能家庭成员,如os.path)。isfile os.path。isdir os.path。对轻微不同行为的lexists)

    os.path.exists(path)
    

    Return True if path refers to an existing path or an open file descriptor. Returns False for broken symbolic links. On some platforms, this function may return False if permission is not granted to execute os.stat() on the requested file, even if the path physically exists.

    返回True,如果path引用了现有路径或打开的文件描述符。返回False用于中断符号链接。在某些平台上,如果不允许在请求的文件上执行os.stat(),该函数可能返回False,即使该路径在物理上存在。

    All good, but if following the import tree:

    一切都好,但如果遵循进口树:

    • os.path - posixpath.py (ntpath.py)

      操作系统。路径- posixpath。py(ntpath.py)

      • genericpath.py, line ~#20+

        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
        

    it's just a try/except block around [Python]: os.stat(path, *, dir_fd=None, follow_symlinks=True). So, your code is try/except free, but lower in the framestack there's (at least) one such block. This also applies to other funcs (including os.path.isfile).

    它只是一个尝试/除去(Python): os。stat(路径、* dir_fd = None,follow_symlinks = True)。所以,您的代码尝试/除了免费,但是在framestack中更低(至少)有一个这样的块。这也适用于其他函数(包括os.path.isfile)。

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

    1.1。(Python):pathlib.Path.is_file()

    • It's a fancier (and more pythonic) way of handling paths, but
    • 这是一个更好的处理路径的方法,但是。
    • Under the hood, it does exactly the same thing (pathlib.py, line ~#1330):

      在引擎盖下,它做了完全相同的事情(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]: With Statement Context Managers. Either:

    (Python):使用语句上下文管理器。:

    • Create one:

      创建一个:

      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 ...)
      
      • And its usage - I'll replicate the isfile behavior (note that this is just for demonstrating purposes, do not attempt to write such code for production):

        它的用法——我将复制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
        
    • Use [Python]: contextlib.suppress(*exceptions) - which was specifically designed for selectively suppressing exceptions

      使用[Python]: contextlib.抑制(*exception)——它是专门为有选择地抑制异常而设计的。


    But, they seem to be wrappers over try/except/else/finally blocks, as [Python]: The with statement states:

    但是,它们似乎是在尝试/其他/最终块,如[Python]: with语句状态:

    This allows common try...except...finally usage patterns to be encapsulated for convenient reuse.

    这允许共同尝试…除了…最后,将使用模式封装以方便重用。

  3. Filesystem traversal functions (and search the results for matching item(s))

    文件系统遍历函数(并搜索匹配项的结果)

    • [Python]: os.listdir(path='.') (or [Python]: os.scandir(path='.') on Python v3.5+)

      [Python]: os.listdir(path='.)(或[Python]: os.scandir(path='.)在Python v3.5+上)

      Using scandir() instead of listdir() can significantly increase the performance of code that also needs file type or file attribute information, because os.DirEntry objects expose this information if the operating system provides it when scanning a directory. All os.DirEntry methods may perform a system call, but is_dir() and is_file() usually only require a system call for symbolic links; os.DirEntry.stat() always requires a system call on Unix but only requires one for symbolic links on Windows.

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

    • [Python]: os.walk(top, topdown=True, onerror=None, followlinks=False)
      • It uses os.listdir (os.scandir when available)
      • 它使用的操作系统。listdir(操作系统。scandir时可用)
    • (Python):操作系统。walk(top, topdown=True, onerror=None, followlinks=False)使用操作系统。listdir(操作系统。scandir时可用)
    • [Python]: glob.iglob(pathname, recursive=False) ([Python]: glob.glob(pathname, *, recursive=False))
      • Doesn't seem a traversing function per se (at least in some cases), but it still uses os.listdir
      • 它本身并不是一个遍历函数(至少在某些情况下是这样),但是它仍然使用os.listdir。
    • (Python):水珠。iglob(路径名,递归= False)((Python):水珠。glob(路径名,*,递归=False))看起来不是一个遍历函数(至少在某些情况下是这样),但是它仍然使用os.listdir。


    Since these iterate over folders, (in most of the cases) they are inefficient for our problem (there are exceptions, like non wildcarded globbing - as @ShadowRanger pointed out), so I'm not going to insist on them. Not to mention that in some cases, filename processing might be required.

    由于这些迭代遍历了文件夹,(在大多数情况下)它们对我们的问题是低效的(有一些例外,比如不通配符的globbing),所以我不打算坚持它们。更不用说在某些情况下,可能需要文件名处理。

  4. [Python]: os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True) whose behavior is close to os.path.exists (actually it's wider, mainly because of the 2nd argument)

    (Python):操作系统。访问(路径,模式,*,dir_fd=None,有效的id =False, follow_symlinks=True),其行为接近于os.path。存在(实际上它更宽,主要是因为第二个参数)

    • user permissions might restrict the file "visibility" as the doc states:

      ...test if the invoking user has the specified access to path. mode should be F_OK to test the existence of path...

      …测试调用的用户是否具有指定的路径访问权限。模式应该是F_OK来测试路径的存在…

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

    Since I also work in C, I use this method as well because under the hood, it calls native APIs (again, via "${PYTHON_SRC_DIR}/Modules/posixmodule.c"), but it also opens a gate for possible user errors, and it's not as Pythonic as other variants. So, as @AaronHall rightly pointed out, don't use it unless you know what you're doing:

    因为我也在C中工作,所以我也使用这个方法,因为在hood中,它调用native api(同样,通过“${PYTHON_SRC_DIR}/Modules/posixmodule.c”),但是它也为可能的用户错误打开了一个门,它不像其他变体那样是python的。因此,正如@AaronHall正确指出的,除非你知道你在做什么,否则不要使用它:

    • Ux: [man]: ACCESS(2) (!!! pay attention to the note about the security hole its usage might introduce !!!)
    • 用户体验:[人]:访问(2)(! ! !注意安全漏洞的注意,它的使用可能会介绍!!!
    • Win: [MSDN]: GetFileAttributes function
    • 赢得(MSDN)::GetFileAttributes函数

    Note: calling native APIs is also possible via [Python]: ctypes — A foreign function library for Python, but in most cases it's more complicated.

    注意:调用本地api也是可能的,通过[Python]: ctypes——Python的一个外国函数库,但在大多数情况下,它更复杂。

    (Win specific): Since msvcr*(vcruntime*) exports a [MSDN]: _access, _waccess function family as well, here's an example:

    (Win specific):由于msvcr*(vcruntime*)导出了一个[MSDN]: _access, _waccess函数家族,这里有一个例子:

    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
    

    Notes:

    注:

    • Although it's not a good practice, I'm using os.F_OK in the call, but that's just for clarity (its value is 0)
    • 虽然这不是一个好的实践,但我使用的是操作系统。在调用中F_OK,但这只是为了清楚(它的值为0)
    • I'm using _waccess so that the same code works on Python3 and Python2 (in spite of unicode related differences between them)
    • 我使用的是_waccess,以便在Python3和Python2上使用相同的代码(尽管它们之间有unicode相关的差异)
    • Although this targets a very specific area, it was not mentioned in any of the previous answers
    • 虽然这个目标是一个非常具体的领域,但在之前的任何一个答案中都没有提及。


    The Lnx (Ubtu (16 x64)) counterpart as well:

    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
    

    Notes:

    注:

    • Instead hardcoding libc's path ("/lib/x86_64-linux-gnu/libc.so.6") which may (and most likely, will) vary across systems, None (or the empty string) can be passed to CDLL constructor (ctypes.CDLL(None).access(b"/tmp", os.F_OK)). According to [man]: DLOPEN(3):

      相反,硬编码libc的路径(“/lib/x86_64-linux-gnu/libc.so.6”)可能(而且很可能会)在不同的系统中不同,没有(或者空字符串)可以传递给CDLL构造函数(ctypes.CDLL(None)。访问(b“/ tmp”,os.F_OK))。根据[人]:DLOPEN(3):

      If filename is NULL, then the returned handle is for the main program. When given to dlsym(), this handle causes a search for a symbol in the main program, followed by all shared objects loaded at program startup, and then all shared objects loaded by dlopen() with the flag RTLD_GLOBAL.

      如果文件名是NULL,那么返回的句柄是主程序。当给dlsym()时,这个句柄会在主程序中搜索一个符号,然后在程序启动时加载所有共享的对象,然后用RTLD_GLOBAL标记dlopen()加载的所有共享对象。

      • Main (current) program (python) is linked against libc, so its symbols (including access) will be loaded
      • Main (current)程序(python)与libc链接,因此它的符号(包括访问)将被加载。
      • This has to be handled with care, since functions like main, Py_Main and (all the) others are available; calling them could have disastrous effects (on the current program)
      • 这必须小心处理,因为像main、Py_Main和(所有)其他功能都可用;调用它们可能会带来灾难性的影响(在当前的程序中)
      • This doesn't also apply to Win (but that's not such a big deal, since msvcrt.dll is located in "%SystemRoot%\System32" which is in %PATH% by default). I wanted to take things further and replicate this behavior on Win (and submit a patch), but as it turns out, [MSDN]: GetProcAddress function only "sees" exported symbols, so unless someone declares the functions in the main executable as __declspec(dllexport) (why on Earth the regular person would do that?), the main program is loadable but pretty much unusable
      • 这并不适用于Win(但这并不是什么大问题,因为msvcrt)。dll位于“% systemroot% \System32”中,默认情况下是%PATH%。我想进一步和复制这种行为赢得(并提交补丁),但事实证明,[MSDN]:GetProcAddress函数只“看到”导出的符号,所以除非有人宣称的功能主要可执行文件使用__declspec(dllexport)(为什么在地球上正常的人会这么做?),主程序可加载,但几乎无法使用
  5. Install some 3rd Party module with filesystem capabilities

    使用文件系统功能安装一些第三方模块。

    Most likely, will rely on one of the ways above (maybe with slight customizations).
    One example would be (again, Win specific) [GitHub]: Python for Windows (pywin32) Extensions, which is a Python wrapper over WINAPIs.

    最有可能的是,它将依赖于上面的一种方法(可能有轻微的自定义)。一个例子是(再次,赢得特定的)[GitHub]:用于Windows的Python (pywin32)扩展,它是针对winapi的Python包装器。

    But, since this is more like a workaround, I'm stopping here.

    但是,既然这更像是一个变通方法,我就停在这里。

  6. Another (lame) workaround (gainarie) is (as I like to call it,) the sysadmin approach: use Python as a wrapper to execute shell commands

    另一个(笨拙的)解决方案(我喜欢这样称呼它):sysadmin方法:使用Python作为执行shell命令的包装器。

    • Win:

      赢得:

      (py35x64_test) e:\Work\Dev\*\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\*\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):

      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
      

Bottom line:

底线:

  • Do use try / except / else / finally blocks, because they can prevent you running into a series of nasty problems. A counter-example that I can think of, is performance: such blocks are costly, so try not to place them in code that it's supposed to run hundreds of thousands times per second (but since (in most cases) it involves disk access, it won't be the case).
  • 使用try / except / else / finally块,因为它们可以防止你遇到一系列严重的问题。我可以想到的一个反例是性能:这些块非常昂贵,所以尽量不要把它们放在代码中,它应该每秒运行数十万次(但是因为(在大多数情况下)它涉及到磁盘访问,它不会是这样的情况)。

Final note(s):

最后注意(s):

  • I will try to keep it up to date, any suggestions are welcome, I will incorporate anything useful that will come up into the answer
  • 我会尽量保持最新的,任何建议都是欢迎的,我会把任何有用的东西加入到答案中。

#11


89  

How do I check whether a file exists, using Python, without using a try statement?

Now available since Python 3.4, import and instantiate a Path object with the file name, and check the is_file method (note that this returns True for symlinks pointing to regular files as well):

现在,从Python 3.4开始,导入并实例化一个带有文件名的路径对象,并检查is_file方法(注意,这个返回的结果对于指向普通文件的符号链接也是正确的):

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

If you're on Python 2, you can backport the pathlib module from pypi, pathlib2, or otherwise check isfile from the os.path module:

如果您使用的是python2,您可以从pypi、pathlib2或从操作系统中检查isfile来支持pathlib模块。路径模块:

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

Now the above is probably the best pragmatic direct answer here, but there's the possibility of a race condition (depending on what you're trying to accomplish), and the fact that the underlying implementation uses a try, but Python uses try everywhere in its implementation.

现在,上面可能是最实用的直接回答,但是有可能出现竞态条件(取决于您要完成的任务),以及底层实现使用了一个尝试,但是Python在实现中到处尝试。

Because Python uses try everywhere, there's really no reason to avoid an implementation that uses it.

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

But the rest of this answer attempts to consider these caveats.

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

Longer, much more pedantic answer

Available since Python 3.4, use the new Path object in pathlib. Note that .exists is not quite right, because directories are not files (except in the unix sense that everything is a file).

从Python 3.4开始,在pathlib中使用新的Path对象。注意,存在并不完全正确,因为目录不是文件(除非在unix中,所有东西都是文件)。

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

So we need to use is_file:

所以我们需要使用is_file:

>>> root.is_file()
False

Here's the help on is_file:

下面是is_file的帮助:

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

So let's get a file that we know is a file:

让我们得到一个文件,我们知道它是一个文件

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

By default, NamedTemporaryFile deletes the file when closed (and will automatically close when no more references exist to it).

默认情况下,NamedTemporaryFile在关闭时删除文件(当没有更多引用时,它将自动关闭)。

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

If you dig into the implementation, though, you'll see that is_file uses try:

但是,如果深入到实现中,您将看到is_file使用了try:

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

Race Conditions: Why we like try

We like try because it avoids race conditions. With try, you simply attempt to read your file, expecting it to be there, and if not, you catch the exception and perform whatever fallback behavior makes sense.

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

If you want to check that a file exists before you attempt to read it, and you might be deleting it and then you might be using multiple threads or processes, or another program knows about that file and could delete it - you risk the chance of a race condition if you check it exists, because you are then racing to open it before its condition (its existence) changes.

如果你想检查一个文件是否存在在你试图读它之前,你可能会删除它,然后你可能会使用多个线程或进程,或另一个程序知道该文件,可以删除它——你风险的机会竞争条件如果你检查它的存在,因为你是那么急于打开它之前条件(存在)的变化。

Race conditions are very hard to debug because there's a very small window in which they can cause your program to fail.

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

But if this is your motivation, you can get the value of a try statement by using the suppress context manager.

但是,如果这是您的动机,您可以使用抑制上下文管理器来获得try语句的值。

Avoiding race conditions without a try statement: suppress

Python 3.4 gives us the suppress context manager (previously the ignore context manager), which does semantically exactly the same thing in fewer lines, while also (at least superficially) meeting the original ask to avoid a try statement:

Python 3.4为我们提供了抑制上下文管理器(以前是忽略上下文管理器),它在语义上完全相同,在更少的行中,同时(至少在表面上)满足原始请求,以避免尝试语句:

from contextlib import suppress
from pathlib import Path

Usage:

用法:

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

For earlier Pythons, you could roll your own suppress, but without a try will be more verbose than with. I do believe this actually is the only answer that doesn't use try at any level in the Python that can be applied to prior to Python 3.4 because it uses a context manager instead:

对于较早的python,您可以自己滚动自己的抑制,但是没有尝试将会比使用更冗长。我相信这实际上是唯一一个不使用Python中任何级别的尝试的答案,因为它使用了上下文管理器来代替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)

Perhaps easier with a try:

或许尝试一下更容易:

from contextlib import contextmanager

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

Other options that don't meet the ask for "without try":

isfile

isfile

import os
os.path.isfile(path)

from the docs:

从文档:

os.path.isfile(path)

os.path.isfile(路径)

Return True if path is an existing regular file. This follows symbolic links, so both islink() and isfile() can be true for the same path.

如果路径是现有的常规文件,则返回True。这将遵循符号链接,因此islink()和isfile()都适用于相同的路径。

But if you examine the source of this function, you'll see it actually does use a try statement:

但是如果你检查这个函数的源,你会发现它确实使用了一个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

All it's doing is using the given path to see if it can get stats on it, catching OSError and then checking if it's a file if it didn't raise the exception.

它所做的就是使用给定的路径来查看它是否可以获得数据,捕获OSError,然后检查它是否是一个文件,如果它没有引发异常。

If you intend to do something with the file, I would suggest directly attempting it with a try-except to avoid a race condition:

如果您打算对该文件做一些事情,我建议您直接尝试,除非是为了避免竞态条件:

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

os.access

os.access

Available for Unix and Windows is os.access, but to use you must pass flags, and it does not differentiate between files and directories. This is more used to test if the real invoking user has access in an elevated privilege environment:

Unix和Windows的可用操作系统是os。访问,但是要使用您必须传递标志,并且它不区分文件和目录。这更用于测试实际调用用户是否具有较高的特权环境中的访问权限:

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

It also suffers from the same race condition problems as isfile. From the docs:

它也有与isfile相同的竞争条件问题。从文档:

Note: Using access() to check if a user is authorized to e.g. open a file before actually doing so using open() creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it. It’s preferable to use EAFP techniques. For example:

注意:使用access()来检查用户是否有权在实际使用open()之前打开文件,从而创建一个安全漏洞,因为用户可能会利用检查和打开文件之间的短时间间隔来操作它。最好使用EAFP技术。例如:

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

is better written as:

是更好的写为:

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

Avoid using os.access. It is a low level function that has more opportunities for user error than the higher level objects and functions discussed above.

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

Criticism of another answer:

Another answer says this about os.access:

另一个答案是关于os的。

Personally, I prefer this one because under the hood, it calls native APIs (via "${PYTHON_SRC_DIR}/Modules/posixmodule.c"), but it also opens a gate for possible user errors, and it's not as Pythonic as other variants:

就我个人而言,我更喜欢这一种,因为在它的底层,它调用本地api(通过“${PYTHON_SRC_DIR}/模块/posixmodule.c”),但是它也为可能的用户错误打开了一个门,它不像其他变体那样是python的:

This answer says it prefers a non-Pythonic, error-prone method, with no justification. It seems to encourage users to use low-level APIs without understanding them.

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

It also creates a context manager which, by unconditionally returning True, allows all Exceptions (including KeyboardInterrupt and SystemExit!) to pass silently, which is a good way to hide bugs.

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

This seems to encourage users to adopt poor practices.

这似乎鼓励用户采用糟糕的实践。

#12


73  

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

Importing os makes it easier to navigate and perform standard actions with your operating system.

导入操作系统使操作系统更容易导航和执行标准操作。

For reference also see How to check whether a file exists using Python?

对于引用,还可以查看如何检查是否存在使用Python的文件?

If you need high-level operations, use shutil.

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

#13


61  

Testing for files and folders with os.path.isfile(), os.path.isdir() and os.path.exists()

测试文件和文件夹与os.path.isfile()、os.path.isdir()和os.path.exists()

Assuming that the "path" is a valid path, this table shows what is returned by each function for files and folders:

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

如何检查文件是否存在?

You can also test if a file is a certain type of file using os.path.splitext() to get the extension (if you don't already know it)

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

#14


55  

It doesn't seem like there's a meaningful functional difference between try/except and isfile(), so you should use which one makes sense.

在try/except和isfile()之间似乎不存在有意义的功能差异,所以您应该使用哪一个是有意义的。

If you want to read a file, if it exists, do

如果您想要读取一个文件,如果它存在,请执行。

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

But if you just wanted to rename a file if it exists, and therefore don't need to open it, do

但是,如果您只是想重命名一个文件,如果它存在,因此不需要打开它,那么做。

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

If you want to write to a file, if it doesn't exist, do

如果您想要写入一个文件,如果它不存在,请执行。

# 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'

If you need file locking, that's a different matter.

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

#15


55  

In 2016 the best way is still using os.path.isfile:

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

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

Or in Python 3 you can use pathlib:

或者在python3里你可以使用pathlib:

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

#16


48  

You could try this (safer):

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

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

The ouput would be:

的输出是:

([Errno 2] No such file or directory: 'whatever.txt')

([Errno 2]没有这样的文件或目录:“whatever.txt”)

Then, depending on the result, your program can just keep running from there or you can code to stop it if you want.

然后,根据结果,您的程序可以继续运行,或者您可以编写代码来阻止它。

#17


43  

Although I always recommend using try and except statements, here are a few possibilities for you (my personal favourite is using os.access):

虽然我总是推荐使用try和except,但这里有一些可能性(我个人最喜欢使用os.access):

  1. Try opening the file:

    试着打开文件:

    Opening the file will always verify the existence of the file. You can make a function just like so:

    打开文件将始终验证文件的存在。你可以这样做:

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

    If it's False, it will stop execution with an unhanded IOError or OSError in later versions of Python. To catch the exception, you have to use a try except clause. Of course, you can always use a try except` statement like so (thanks to hsandt for making me think):

    如果它是错误的,那么它将在Python的后续版本中以一个未提交的IOError或OSError停止执行。要捕获异常,您必须使用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. Use os.path.exists(path):

    使用os.path.exists(路径):

    This will check the existence of what you specify. However, it checks for files and directories so beware about how you use it.

    这将检查您指定的内容是否存在。但是,它检查文件和目录,所以要小心使用它。

    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. Use os.access(path, mode):

    使用操作系统。访问(路径、模式):

    This will check whether you have access to the file. It will check for permissions. Based on the os.py documentation, typing in os.F_OK, it will check the existence of the path. However, using this will create a security hole, as someone can attack your file using the time between checking the permissions and opening the file. You should instead go directly to opening the file instead of checking its permissions. (EAFP vs LBYP). If you're not going to open the file afterwards, and only checking its existence, then you can use this.

    这将检查您是否能够访问该文件。它将检查权限。基于操作系统。py文档,在操作系统中输入。F_OK,它将检查路径的存在。但是,使用此方法将创建一个安全漏洞,因为有人可以在检查权限和打开文件之间使用时间来攻击您的文件。相反,您应该直接打开文件,而不是检查其权限。(EAFP vs LBYP)。如果您以后不打算打开文件,并且只检查它的存在,那么您可以使用它。

    Anyway, here:

    不管怎样,在这里:

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

I should also mention that there are two ways that you will not be able to verify the existence of a file. Either the issue will be permission denied or no such file or directory. If you catch an IOError, set the IOError as e (like my first option), and then type in print(e.args) so that you can hopefully determine your issue. I hope it helps! :)

我还应该提到,有两种方法无法验证文件的存在。这个问题将被拒绝,或者没有这个文件或目录。如果您捕获了一个IOError,将IOError设置为e(像我的第一个选项一样),然后输入print(.args),这样您就可以希望确定您的问题了。我希望它可以帮助!:)

#18


31  

Additionally, os.access():

此外,os.access():

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

Being R_OK, W_OK, and X_OK the flags to test for permissions (doc).

使用R_OK、W_OK和X_OK标记来测试权限(doc)。

#19


31  

In Python 3.4 the language provides a new module to manage files:

在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.

#20


18  

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

Raising exceptions is considered to be an acceptable, and Pythonic, approach for flow control in your program. Consider handling missing files with IOErrors. In this situation, an IOError exception will be raised if the file exists but the user does not have read permissions.

在您的程序中,提高异常被认为是一种可接受的、和python的方法。考虑使用IOErrors处理丢失的文件。在这种情况下,如果文件存在,则会引发IOError异常,但用户没有读权限。

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

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

#21


16  

You can write Brian's suggestion without the try:.

你可以不用试着写布莱恩的建议:。

from contextlib import suppress

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

suppress is part of Python 3.4. In older releases you can quickly write your own suppress:

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

from contextlib import contextmanager

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

#22


15  

Here's a 1 line Python command for the Linux command line environment. I find this VERY HANDY since I'm not such a hot Bash guy.

这里是一个用于Linux命令行环境的1行Python命令。我觉得这很方便,因为我不是一个很热情的家伙。

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

I hope this is helpful.

我希望这是有帮助的。

#23


15  

Adding one more slight variation which isn't exactly reflected in the other answers.

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

This will handle the case of the file_path being None or empty string.

这将处理file_path为None或空字符串的情况。

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

Adding a variant based on suggestion from Shahbaz

根据Shahbaz的建议添加一个变体。

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

Adding a variant based on suggestion from Peter Wood

根据Peter Wood的建议添加一个变体。

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

#24


14  

I'm the author of a package that's been around for about 10 years, and it has a function that addresses this question directly. Basically, if you are on a non-Windows system, it uses Popen to access find. However, if you are on Windows, it replicates find with an efficient filesystem walker.

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

The code itself does not use a try block… except in determining the operating system and thus steering you to the "Unix"-style find or the hand-buillt find. Timing tests showed that the try was faster in determining the OS, so I did use one there (but nowhere else).

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

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

And the doc…

和医生……

>>> 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']

>>>

The implementation, if you care to look, is here: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190

如果你想看的话,它的实现是:https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190。

#25


12  

Date:2017-12-04

日期:2017-12-04

Every possible solution has been listed in other answers.

所有可能的解决方案都列在其他答案中。

An intuitive and arguable way to check if a file exists is the following:

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

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

I made an exhaustive cheatsheet for your reference:

我做了一个详尽的备查表,供你参考:

#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


11  

You can use the "OS" library of Python:

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

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

#27


11  

How do I check whether a file exists, without using the try statement?

我如何检查文件是否存在,而不使用try语句?

In 2016, this is still arguably the easiest way to check if both a file exists and if it is a file:

在2016年,这仍然可以说是检查文件是否存在的最简单方法,如果它是一个文件:

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

isfile is actually just a helper method that internally uses os.stat and stat.S_ISREG(mode) underneath. This os.stat is a lower-level method that will provide you with detailed information about files, directories, sockets, buffers, and more. More about os.stat here

isfile实际上只是一个内部使用操作系统的辅助方法。统计和stat.S_ISREG(模式)。这个操作系统。stat是一种较低级别的方法,它将为您提供关于文件、目录、套接字、缓冲区等的详细信息。更多关于操作系统。统计在这里

Note: However, this approach will not lock the file in any way and therefore your code can become vulnerable to "time of check to time of use" (TOCTTOU) bugs.

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

So raising exceptions is considered to be an acceptable, and Pythonic, approach for flow control in your program. And one should consider handling missing files with IOErrors, rather than if statements (just an advice).

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

#28


10  

import os
path = /path/to/dir

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

This is helpful when checking for several files. Or you want to do a set intersection/ subtraction with an existing list.

这在检查几个文件时很有用。或者你想用一个已有的列表来做一个集的交集/减法。

#29


10  

You can use the following open method to check if a file exists + readable:

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

open(inputFile, 'r')

#30


9  

If the file is for opening you could use one of the following techniques:

如果文件是开放的,您可以使用以下技术之一:

>>> 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!')