如何检查文件是否存在?

[英]How do I check whether a file exists?


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

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

39 个解决方案

#1


3817  

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(),那么在尝试打开它时使用try更安全。检查和打开文件会有被删除或移动的风险,或者在检查和尝试打开文件之间的风险。

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

要检查路径对象是否独立于它是文件还是目录而存在,请使用exist ():

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 existelse:    # exists

#2


1571  

You have the os.path.exists function:

你有os.path。存在功能:

import os.pathos.path.exists(file_path)

This returns True for both files and directories but you can instead use

这对于文件和目录都返回True,但是您可以使用

os.path.isfile(file_name)

to test if it's a file specifically. It follows symlinks.

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

#3


826  

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()不同,exist()对于目录返回True。因此,如果您只想要纯文件或目录,您将使用isfile()或exist()。这是一个简单的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


450  

import os.pathif os.path.isfile(filepath):

#5


206  

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

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

import osimport os.pathPATH='./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


190  

import osos.path.exists(path) # Returns whether the path (directory or file) exists or notos.path.isfile(path) # Returns whether the file exists or not

#7


134  

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 osfname = "foo.txt"if os.path.isfile(fname):    print("file does exist at this time")else:    print("no such file exists at this time")

#8


118  

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 pathlibp = 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/except块:

try:    with p.open() as f:        # do awesome stuffexcept 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模块中有很多很酷的东西:方便的全局查找、检查文件的所有者、更容易的路径连接等等。如果您使用的是较老的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 versionsimport pathlib2 as pathlib

#9


114  

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

    exist (path)(还检查其他函数家族成员,如os.path)。isfile os.path。isdir os.path。稍微不同的行为

    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。返回错误的符号链接。在某些平台上,如果未授予在请求文件上执行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附近的一个try/except块。stat(路径、* dir_fd = None,follow_symlinks = True)。因此,您的代码是try/except free,但是在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
    • 这是一种更奇特(更python化)的路径处理方式,但是
    • 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 osimport statdef 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:

    但是,它们似乎是try/except/else/finally块的包装器,如[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='.')

      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()通常只需要系统调用符号链接;stat()总是需要对Unix进行系统调用,但只需要对Windows上的符号链接进行系统调用。

    • [Python]: os.walk(top, topdown=True, onerror=None, followlinks=False)
      • It uses os.listdir (os.scandir when available)
      • 它使用的操作系统。listdir(操作系统。scandir时可用)
    • (Python):操作系统。它使用的是os (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(pathname, *, recursive=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.

    由于这些循环遍历文件夹,(在大多数情况下)它们对于我们的问题是无效的(有一些例外,如@ShadowRanger指出的非通配符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):操作系统。访问(path, mode, *, dir_fd=None, effective ve_ids=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语言中工作,所以我也使用这个方法,因为在底层,它调用本地api(同样,通过“${PYTHON_SRC_DIR}/Modules/posixmodu . 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 win32Type "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)
    • 虽然这不是一个好的实践,但我正在使用os。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 (16x64))对应文件:

    Python 3.5.2 (default, Nov 17 2016, 17:05:23)[GCC 5.4.0 20160609] on linuxType "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.

      如果文件名为空,则返回的句柄用于主程序。当给定dlsym()时,该句柄将导致在主程序中搜索符号,然后是在程序启动时加载的所有共享对象,然后是由dlopen()加载的带有标记RTLD_GLOBAL的所有共享对象。

      • Main (current) program (python) is linked against libc, so its symbols (including access) will be loaded
      • 主(当前)程序(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
      • 这也不适用于获胜(但这并不是什么大问题,因为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.

    最有可能的是,将依赖上面的一种方法(可能需要稍微定制)。一个例子是(同样是Win specific) [GitHub]: Windows (pywin32)扩展的Python,它是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\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):

      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
  • 我将尽量保持它的最新,欢迎任何建议,我将纳入任何有用的东西,将出现在回答

#10


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:

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

#11


95  

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.

现在,上面的内容可能是最佳的实用直接答案,但是有可能出现竞争条件(取决于您想要完成什么),而且底层实现使用try,但是Python在其实现中到处都使用try。

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

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

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对象。注意,.exist并不完全正确,因为目录不是文件(除了在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.

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

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 suppressfrom 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@contextmanagerdef suppress(*exceptions):    try:        yield    except exceptions:        pass

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

isfile

isfile

import osos.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 symlinksdef 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.errorTrue

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-except以避免竞争条件:

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 osos.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.    raiseelse:    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.access:

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}/Modules/posixmodu .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


74  

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


62  

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:

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

enter image description here

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

#14


57  

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:

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

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

#15


56  

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 2if not os.path.isfile(filepath):    f = open(filepath, 'w')# python 3, x opens for exclusive creation, failing if the file already existstry:    f = open(filepath, 'wx')except IOError:    print 'file already exists'

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

如果需要文件锁定,那就另当别论了。

#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 and 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 IOErroror OSError in later versions of Python. To catch the exception,you have to use a try except clause. Of course, you can alwaysuse a try except` statement like so (thanks to hsandtfor making me think):

    如果它是假的,那么它将在Python的后续版本中使用一个unhand IOErroror OSError停止执行。要捕获异常,必须使用try except子句。当然,你可以尝试一下,除了“so like so”(感谢hsandtfor让我思考):

    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文档,输入os。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(e.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 pathlibpath = 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化的方法。考虑使用ioerror处理丢失的文件。在这种情况下,如果文件存在,则会引发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 suppresswith suppress(IOError), open('filename'):    process()

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

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

from contextlib import contextmanager@contextmanagerdef 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来访问查找。但是,如果您在Windows上,它会使用高效的文件系统巡查器来复制find。

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/89f90fb308f308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.# L190

#25


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

#26


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 osos.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)错误的影响。

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语句(只是一个建议)。

#27


11  

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 osos.path.isfile('~/file.md')    # Returns True if exists, else Falseadditionaly check a diros.path.isdir('~/folder') # Returns True if the folder exists, else Falsecheck either a dir or a fileos.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']}

#28


11  

Check file or directory exists

You can follow these three ways:

你可以遵循以下三种方法:

Note1: The os.path.isfile used only for files

注一:os.path。isfile仅用于文件。

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

Note2: The os.path.exists used for both files and directories

注2:os.path。存在用于文件和目录。

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

The pathlib.Path method (included in Python 3+, installable with pip for Python 2)

pathlib。路径方法(包含在Python 3+中,用于Python 2的pip可安装)

from pathlib import PathPath(filename).exists()

#29


10  

import ospath = /path/to/dirroot,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.

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

#30


10  

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

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

open(inputFile, 'r')
智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2008/09/17/beaddbc0313c9974ea3e3d9848972c57.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告