python:我如何检查一个文件是否存在没有异常?

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


如果检查的原因是为了执行if file_exists: open_it()之类的操作,那么在尝试打开它时使用try会更安全。检查并打开文件会有文件被删除或移动的风险,或者在检查和试图打开文件之间的某些风险。

如果不打算立即打开文件,可以使用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.

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

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

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

1
2
3
4
5
from pathlib import Path

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

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

1
2
if my_file.is_dir():
    # directory exists

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

1
2
if my_file.exists():
    # path exists

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

1
2
3
4
5
6
try:
    my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
    # doesn't exist
else:
    # exists


你有os.path.exists函数:

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

这将为文件和目录返回True,但是您可以使用它

1
os.path.isfile(file_path)

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


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

1
2
3
4
5
6
7
8
9
10
11
12
>>> 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


1
2
3
import os.path

if os.path.isfile(filepath):


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

1
2
3
4
5
6
7
8
9
import os
import os.path

PATH='./file.txt'

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


1
2
3
import os
os.path.exists(path) # Returns whether the path (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not

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

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

问题陈述:

检查文件(有争议的:也文件夹("特殊"文件)的存在不要使用try / except / else / finally块

可能的解决方式:

[Python 3]: os.path.exists(path)(也可以检查其他函数家族成员,如os.path.isfileos.path.isdiros.path.lexists,以获得稍微不同的行为)

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

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

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

genericpath。py,行~ # 20 +

1
2
3
4
5
6
7
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

它只是围绕[python3]: os的一个try / except块。stat(path, *, dir_fd=None, follow_symlinks=True)。因此,您的代码是try / except free,但在framestack下面有(至少)一个这样的块。这也适用于其他函数(包括os.path.isfile)。

1.1。Python [3]: Path.is_file ()

这是一种更奇特(和更python化)的路径处理方法,但是

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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

[Python 3]:使用语句上下文管理器。:

创建一个:

1
2
3
4
5
6
7
8
9
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 ...)

和它的用法-我将复制os.path.isfile行为(注意,这只是为了演示目的,不要试图编写这样的代码用于生产):

1
2
3
4
5
6
7
8
9
import os
import stat


def isfile_seaman(path):  # Dummy func
    result = False
    with Swallow():
        result = stat.S_ISREG(os.stat(path).st_mode)
    return result

使用[Python 3]: context .suppress(*exception)——这是专门为选择性地抑制异常而设计的

但是,它们似乎是try / except / else / finally块的包装器,正如[Python 3]: with语句声明:

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

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

[Python 3]: os.listdir(path='.')(或[Python 3]: os.scandir(path='.') on Python v3.5+, backport: [PyPI]: scandir)

在引擎盖下,两个用途:

Nix: [man7]: OPENDIR(3) / [man7]: READDIR(3) / [man7]: CLOSEDIR(3)胜利:[女士。: FindFirstFileW函数/ [MS。: FindNextFileW函数/ [MS。文档:FindClose函数

通过[GitHub]: python/cpython - (master) cpython/Modules/posixmodule.c

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.

[Python 3]:操作系统。walk(top, topdown=True, onerror=None, followlinks=False)它使用os.listdir (os.scandir当可用时)【Python 3]:一团。iglob(路径名,*,递归=False)(或其前身:glob.glob)看起来并不是遍历函数(至少在某些情况下),但是它仍然使用os.listdir

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

[Python 3]:操作系统。访问(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True),其行为接近os.path.exists(实际上它更宽,主要是因为2和参数)

如doc所述,用户权限可能会限制文件的"可见性":

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

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

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

Nix: [man7]: ACCESS(2) (!!)注意注意其使用可能会带来的安全漏洞!!)胜利:[女士。文档:GetFileAttributesW函数

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

(Win specific):因为vcruntime* (msvcr*) .dll导出了一个[MS。: _access, _waccess函数家族,这里有一个例子:

1
2
3
4
5
6
7
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.notexist", os.F_OK)
-1

注:

虽然这不是一个好的实践,但我在调用中使用了os.F_OK,但这只是为了清楚起见(它的值是0)我使用_waccess以便在Python3和Python2上运行相同的代码(尽管它们之间存在unicode相关的差异)虽然这是针对一个非常具体的领域,但在之前的任何回答中都没有提到

Lnx (Ubtu (16x64))同样适用于:

1
2
3
4
5
6
7
8
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"/tmp.notexist", os.F_OK)
-1

注:

相反,硬编码libc的路径("/lib/x86_64-linux-gnu/libc.so.6")可能(而且很可能)在不同的系统中有所不同,因此不能(或空字符串)传递给CDLL构造函数(ctypes.CDLL(None).access(b"/tmp", os.F_OK))。根据[man7]: 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.

Main (current) program (python)链接到libc,因此它的符号(包括访问)将被加载这必须小心处理,因为main、Py_Main和(所有)其他函数都是可用的;调用它们可能会(对当前程序)产生灾难性的影响这并不适用于Win(但这并不重要,因为msvcr .dll位于"%SystemRoot%System32"中,默认情况下位于%PATH%中)。我想更进一步,在Win上复制这个行为(并提交一个补丁),但事实证明,[MS。GetProcAddress函数只"看到"导出的符号,所以除非有人在主可执行文件中声明函数为__declspec(dllexport)(为什么普通人会这样做呢?),否则主程序是可加载的,但几乎不可用

安装具有文件系统功能的第三方模块

最有可能的是,将依赖于上面的一种方法(可能需要少量的定制)。一个例子是(同样是特定于Win的)[GitHub]: mhammond/pywin32 - Python for Windows (pywin32)扩展,这是winapi上的Python包装器。

但是,由于这更像是一种变通方法,我就讲到这里。

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

赢得:

1
2
3
4
5
(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)):

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

底线:

一定要使用try / except / else / finally块,因为它们可以防止您遇到一系列棘手的问题。我能想到的一个反例是性能:这样的块非常昂贵,所以尽量不要将它们放在应该每秒运行数十万次的代码中(但由于(在大多数情况下)它涉及磁盘访问,所以不会出现这种情况)。

最后注意(s):

我会努力保持它的最新,任何建议都是受欢迎的,我会纳入任何有用的,将出现在答案


这是检查文件是否存在的最简单方法。检查时存在的文件不能保证在需要打开它时仍然存在。

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


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

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

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

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

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

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

然后导入如下:

1
2
# Older Python versions
import pathlib2 as pathlib

更喜欢try语句。它被认为是更好的风格和避免种族条件。

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

Style: http://all捐助ney.com/sd/notes/notes11.txt的"处理异常情况"部分避免竞态条件


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

从Python 3.4开始就可用了,导入并实例化一个带有文件名的Path对象,并检查is_file方法(注意,对于指向常规文件的符号链接,也会返回True):

1
2
3
4
5
6
7
>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

如果使用Python 2,可以从pypi、pathlib2中备份pathlib模块,或者从os.path模块中检查isfile:

1
2
3
4
5
6
7
>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

现在,上面的内容可能是最实用的直接答案,但是可能存在竞态条件(取决于您试图完成的内容),而且底层实现使用try,而Python在其实现中到处使用try

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

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

更长,答案更迂腐

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

1
2
3
4
>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

所以我们需要使用is_file:

1
2
>>> root.is_file()
False

这里是关于is_file的帮助:

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

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

1
2
3
4
5
6
7
>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True

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

1
2
3
4
5
>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

但是,如果深入研究实现,就会发现is_file使用了try:

1
2
3
4
5
6
7
8
9
10
11
12
13
def is_file(self):
   """
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).
   """

    try:
        return S_ISREG(self.stat().st_mode)
    except OSError as e:
        if e.errno not in (ENOENT, ENOTDIR):
            raise
        # Path doesn't exist or is a broken symlink
        # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
        return False

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

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

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

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

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

避免没有try语句的竞态条件:suppress

Python 3.4给我们提供了suppress上下文管理器(以前是ignore上下文管理器),它在更少的行中执行语义上完全相同的操作,同时(至少表面上)满足原始的请求,以避免使用try语句:

1
2
from contextlib import suppress
from pathlib import Path

用法:

1
2
3
4
5
6
7
8
9
>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
...
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
...
>>>

对于早期的python,您可以滚动自己的suppress,但是没有try将比使用它更冗长。我相信这实际上是唯一一个在Python中没有使用try在Python 3.4之前的任何级别的答案,因为它使用了一个上下文管理器:

1
2
3
4
5
6
7
8
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)

也许尝试一下会更容易:

1
2
3
4
5
6
7
8
from contextlib import contextmanager

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

其他不符合"无需尝试"要求的选项:

isfile

1
2
import os
os.path.isfile(path)

从文档:

os.path.isfile(path)

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.

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

1
2
3
4
5
6
7
8
9
# 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)
1
2
>>> OSError is os.error
True

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

如果您打算对该文件做些什么,我建议您直接尝试一下—除非避免竞态条件:

1
2
3
4
5
try:
    with open(path) as f:
        f.read()
except OSError:
    pass

os.access

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

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

它也有与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:

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

is better written as:

1
2
3
4
5
6
7
8
9
10
try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return"some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

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

批评另一个答案:

另一个答案是关于os.access:

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:

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

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

这似乎鼓励用户采用不好的实践。


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

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

有关参考资料,请参见如何使用Python检查文件是否存在?

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


测试带有os.path.isfile()os.path.isdir()os.path.exists()的文件和文件夹

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

enter image description here

您还可以使用os.path.splitext()来测试一个文件是否是某种类型的文件,以获得扩展名(如果您还不知道)

1
2
3
4
5
6
>>> 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

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

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

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

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


try/except和isfile()之间似乎没有明显的函数区别,所以您应该使用其中一个。

如果您想要读取一个文件,如果它存在,那么就读取它

1
2
3
4
try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

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

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

如果你想写一个文件,如果它不存在,那就写吧

1
2
3
4
5
6
7
8
9
# 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'

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


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

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

输出将是:

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

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


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

试着打开文件:

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

1
2
3
def File_Existence(filepath):
    f = open(filepath)
    return True

如果它是假的,它将停止执行一个独立的IOError或者在Python的后续版本中使用OSError。为了捕捉异常,你必须使用try except子句。当然,你总是可以的使用try except '语句like so(感谢hsandt)谢谢你让我思考):

1
2
3
4
5
6
7
def File_Existence(filepath):
    try:
        f = open(filepath)
    except IOError, OSError: # Note OSError is for later versions of Python
        return False

    return True

使用os.path.exists(path):

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

1
2
3
4
5
6
7
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

使用os.access(path, mode):

这将检查您是否有权访问该文件。它将检查权限。根据os.py文档,输入os.F_OK,它将检查路径是否存在。但是,使用这种方法会产生一个安全漏洞,因为有人可能会在检查权限和打开文件之间的时间内攻击您的文件。您应该直接打开文件,而不是检查它的权限。(EAFP vs LBYP)。如果以后不打开文件,只检查它是否存在,那么可以使用这个。

不管怎样,在这里:

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

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


日期:2017-12-04

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

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

1
2
3
4
5
6
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')

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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']}

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

1
2
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.


此外,os.access():

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

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


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

1
2
3
4
5
6
7
8
9
10
>>> with open('somefile', 'xt') as f: #Using the x-flag, Python3.3 and above
...     f.write('Hello
'
)

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

更新

为了避免混淆,根据我得到的答案,current answer可以找到一个文件或一个具有给定名称的目录。


1
2
3
4
5
6
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.

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


你可以不用try:来写Brian的建议。

1
2
3
4
from contextlib import suppress

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

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

1
2
3
4
5
6
7
8
from contextlib import contextmanager

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

如果您已经为其他目的导入了NumPy,那么就不需要导入其他库,比如pathlibospaths等等。

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

这将根据它的存在返回真或假。


检查文件或目录是否存在

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

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

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

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

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

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

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

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

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

1
2
3
4
5
6
7
def file_exists(file_path):
    if not file_path:
        return False
    elif not os.path.isfile(file_path):
        return False
    else:
        return True

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

1
2
3
4
5
def file_exists(file_path):
    if not file_path:
        return False
    else:
        return os.path.isfile(file_path)

根据彼得·伍德的建议添加一个变体

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


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

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

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

和医生……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

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

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

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

>>>

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


下面是一个针对Linux命令行环境的1行Python命令。我发现这非常方便,因为我不是一个狂热的Bash家伙。

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

希望这对您有所帮助。


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

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

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

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

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

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


你可以使用Python的"OS"库:

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


1
2
3
4
5
6
import os
path = /path/to/dir

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import os.path

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

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

isReadableFile(path, fileName)


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

1
open(inputFile, 'r')


要检查文件是否存在,

1
2
3
4
5
6
from sys import argv

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


你可以使用操作系统。检查文件是否在某个目录中。

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


1
2
3
4
5
6
7
import os

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

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


你一定要用这个。

1
2
3
4
5
6
from os.path import exists

if exists("file") == True:
    print"File exists."
elif exists("file") == False:
    print"File doesn't exist."


可能不需要,但如果需要,这里有一些代码

1
2
3
4
5
6
7
import os

def file_exists(path, filename)
    for file_or_folder in os.listdir(path):
        if file_or_folder == filename:
            return True
    return False

python方法:以"r+"模式打开文件。这种模式:

允许读取和写入文件将文件指针放在文件的请求处如果文件不存在,将不创建该文件吗

如果您随后想要追加到文件的末尾,请在编写之前查找末尾。这将允许您在文件存在的情况下打开它,或者在不存在的情况下优雅地失败,而不会将程序打开到竞态条件。


如果你想在Bash中做到这一点,它应该是:

1
2
3
if [ -e"$FILE" ]; then
    prog"$FILE"
fi

当我使用Python对一组名称进行更复杂的操作时(因为我有时需要使用Python), try open(file): except:方法并不是真正需要的,因为它不是用来打开文件的Python进程。

在一种情况下,其目的是根据当前是否存在名称列表进行筛选(而且没有进程可能删除文件,也没有安全问题,因为这是在我的Raspberry Pi上,它的SD卡上没有敏感文件)。

我想知道一个"简单模式"的网站是否是个好主意?例如,您可以用它们之间的链接来说明这两种方法,以及关于何时使用哪种模式的讨论链接。


我发现这个字符串时,试图建立以下功能:

检查Django视图中的静态目录中是否存在文件如果文件存在,则以模板形式提供如果文件不存在—在模板中提供一个对话框,说明文件不存在。

在研究了各种解决方案之后,我发现没有一个解决方案可以同时在开发环境(使用本地静态文件)和生产环境(使用S3存储)中工作。

因此以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os.path
import urllib2
from django.templatetags.static import static
from django.contrib.staticfiles import finders

## Determine if file present to serve
doc_title = 'document.pdf'
doc_available = False
try:
    if site_settings.CLOUD_STATIC :
        doc_path = static('app/document/%s' % doc_title)
        try:
            ret = urllib2.urlopen(doc_path)
        except Exception as e:
            pass
        else:
            if ret.code == 200:
                doc_available = True
    else:
        doc_path = finders.find('app/document/%s' % doc_title)
        doc_available = os.path.isfile(doc_path)

except Exception as e:
    doc_path = None

答案可能不是很像蟒蛇,所以请改进。

site_settings。CLOUD_STATIC是一个设置bool,它决定是否应该基于环境使用云存储(可以使用site_settings.DEBUG)。

因此,我将doc_available bool传递给模板并相应地处理。


在这种情况下,您可以检查该文件名是否存在于listdir中。如果没有,则该文件不存在。

1
2
3
4
5
6
7
8
9
10
11
import os
filename = 'D:\\Python\\Python27\\prz\\passwords\\alpa.txt'
li = filename.split('\')
st = '
'
for i in range(0, len(li)-1):
    st = st + li[i] + '
\'
dirlist = os.listdir(st)
if(li[len(li)-1] in dirlist):
    fp = open(filename, '
r')
else:
    print"FILE NOT FOUND"

这是完美的。