当前位置:  开发笔记 > 编程语言 > 正文

如何检查文件是否存在而没有例外?

如何解决《如何检查文件是否存在而没有例外?》经验,为你挑选了33个好方法。

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



1> rslite..:

如果您检查的原因是这样,您可以做类似的事情if file_exists: open_it(),那么使用try围绕尝试打开它更安全.在检查和尝试打开文件时检查然后打开文件被删除或移动的风险或介于两者之间的风险.

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

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

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

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

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

from pathlib import Path

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

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

if my_file.is_dir():
    # directory exists

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

if my_file.exists():
    # path exists

你也可以resolve(strict=True)在一个try块中使用:

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


关于第一个注释(如果在打开之前检查,请使用"try"),不幸的是,如果你想打开以确保它存在之前是不可行的,因为'a'模式将创建(如果不存在).
请注意,`FileNotFoundError`是Python 3中引入的。如果您还需要支持Python 2.7和Python 3,则可以改用`IOError`(这是`FileNotFoundError`的子类)/sf/ask/17360801/ / 1960959

2> PierreBdR..:

你有这个os.path.exists功能:

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

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

os.path.isfile(file_path)

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



3> bortzmeyer..:

不同的是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> Paul..:
import os.path

if os.path.isfile(filepath):



5> Yugal Jindle..:

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

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"


有多个条件,其中一些是多余的,是清晰明确的.
这也是多余的.如果文件不存在,`os.access()`将返回false.
因为你`导入os`,所以你不需要再次`import os.path`,因为它已经是`os`的一部分了.你只需要导入`os.path`如果你只想使用`os.path`中的函数而不是来自`os`本身来导入一个更小的东西,但是当你使用`os.access`和`os时.R_OK`,不需要第二次导入.
@EJP在linux文件中可以存在但不可访问.

6> benefactual..:
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



7> CristiFati..:

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

注意:我要发布的每个Python标准库代码都属于3.5.3版.

问题陈述:

    检查文件(可论证:还是文件夹("特殊"文件)?)存在

    不要使用try/except/else/finally

可能的方法:

    [Python 3]:os.path.存在(路径)(还要检查其他功能的家庭成员一样os.path.isfile,os.path.isdir,os.path.lexists对行为略有不同)

    os.path.exists(path)
    

    返回True如果路径是指现有的路径或一个打开的文件描述符.False损坏的符号链接的返回值.在某些平台上,False如果未授予权限以在请求的文件上执行os.stat(),则此函数可能会返回,即使路径实际存在也是如此.

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

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

    genericpath.py,line ~#20 +

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

    它只是围绕[Python 3]的一个try/except块:os.stat(path,*,dir_fd = None,follow_symlinks = True).所以,你的代码是try/except free,但是在framestack中更低(至少)有一个这样的块.这也适用于其他功能(包括 os.path.isfile).

    1.1.[Python 3]:路径.is_file()

    它是处理路径的更高级(以及更多python ic)方式,但是

    在引擎盖下,它完全相同(pathlib.py,line ~#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
    

    [Python 3]:使用语句上下文管理器.或者:

    创建一个:

    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行为(注意,这只是为了演示的目的,也不会尝试写这样的代码制作):

    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]:contextlib.抑制(*例外) -这是具体地用于选择性地抑制异常设计


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

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

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

    [Python 3]:os.listdir(path ='.')(或[Python 3]:os.scandir(path ='.')在Python v 3.5 +上,backport:[PyPI]:scandir)

    在引擎盖下,两者都使用:

    尼克斯:[man7]:OPENDIR(3)/[man7]:READDIR(3)/[man7]:CLOSEDIR(3)

    Win:[MS.Docs]:FindFirstFileW函数/[MS.Docs]:FindNextFileW函数/[MS.Docs]:FindClose函数

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

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

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

    它使用os.listdir(os.scandir如果可用)

    [Python 3]:glob.iglob(路径名,*,递归=假)(或它的前身:glob.glob)

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


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

    [Python 3]:os.访问(路径,模式,*,dir_fd =无,effective_ids =假follow_symlinks =真)的行为是接近os.path.exists(实际上这部分人主要是因为2的宽度,第二参数)

    用户权限可能会限制文件"可见性",因为doc说明:

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

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

    由于我也是在工作Ç,我用这个方法,以及因为引擎盖下,它调用本地API小号(同样,通过"$ {} PYTHON_SRC_DIR /Modules/posixmodule.c"),但它也开辟了可能的栅极用户错误,它不像其他变种那样是Python ic.因此,正如@AaronHall正确指出的那样,除非你知道你在做什么,否则不要使用它:

    尼克斯:[man7]:访问(2)(!!!注意关于安全漏洞的注意事项,它的用法可能会介绍!!!)

    Win:[MS.Docs]:GetFileAttributesW函数

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

    (Win特定):由于vcruntime*(msvcr*).dll也导出[MS.Docs]:_ 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.notexist", os.F_OK)
    -1
    

    备注:

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

    我正在使用_waccess,因此相同的代码适用于Python3Python2(尽管它们之间存在unicode相关的差异)

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


    LNX(Ubtu(16 64) )的对应,以及:

    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")可能(并且很可能会)在不同系统之间变化,None(或空字符串)可以传递给CDLL构造函数(ctypes.CDLL(None).access(b"/tmp", os.F_OK)).根据[man7]:DLOPEN(3):

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

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

    这必须小心处理,因为main,Py_Main和(所有)其他功能都可用; 打电话给他们可能会产生灾难性后果(在当前的计划中)

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

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

    最有可能的是,它将依赖于上述方法之一(可能需要轻微的自定义).
    一个例子是(再次,Win特定)[GitHub]:mhammond/pywin32 - 用于Windows的Python(pywin32)扩展,它是WINAPI上Python包装器.

    但是,由于这更像是一种解决方法,我在这里停下来.

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

    胜利:

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

    尼克斯(Lnx(Ubtu)):

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

底线:

不要使用尝试//其它/最后块,因为他们可以阻止你运行到一系列讨厌的问题.我能想到的反例是性能:这样的块很昂贵,所以尽量不要将它们放在应该每秒运行数十万次的代码中(但是因为(在大多数情况下)它涉及磁盘访问,情况并非如此).

最后的说明:

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


@ sk8asd123:在注释中很难做到这一点:通常,最好将常量与它们一起使用的函数一起使用.这适用于使用定义相同常量的多个模块,因为有些模块可能不是最新的,并且最好使函数和常量保持同步.使用*ctypes*(直接调用函数)时,我应该定义常量(来自*MSDN*),或者根本不使用常量.这只是我使用的指南,在99.9%它可能没有区别(功能上).
您能详细说明一下吗?“尽管这不是一个好习惯,但我在调用中使用了os.F_OK,但这只是为了清楚起见(其值为0)”
@CristiFati:从3.6版本开始,[`glob.iglob`(和`glob.glob`)都基于`os.scandir`](https://docs.python.org/3/whatsnew/3.6.html #optimizations),所以现在很懒。要在10M文件的目录中获得第一个匹配,您只需扫描直到达到第一个匹配。甚至在3.6之前的版本中,如果您在不使用通配符的情况下使用glob方法,则该功能很聪明:它知道您只能点击一次,因此[将glob简化为os.path.isdir或` os.path.lexists`](https://github.com/python/cpython/blob/3ae41554c69b807659fab815ad5675bed5ae237/Lib/glob.py#L41)(取决于路径是否以`/`结尾)。
我的意见的第二部分(非通配符实际上不会迭代文件夹,也从未如此)确实意味着它是解决该问题的完美解决方案(比直接调用`os.path.isdir`或`os.path慢.lexist`,因为它在确定有效路径之前是一堆Python级别的函数调用和字符串操作,但是没有其他系统调用或I / O工作,这要慢几个数量级。

8> un33k..:

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

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


只要您打算访问该文件,竞争条件_does exists_,无论您的程序如何构建.您的程序无法保证计算机上的其他进程未修改该文件.这就是Eric Lippert所说的[外生异常](http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx).您无法通过事先检查文件的存在来避免它.

9> Cody Piersal..:

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

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

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

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

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

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

然后导入如下:

# Older Python versions
import pathlib2 as pathlib



10> pkoch..:

首选try语句.它被认为是更好的风格,避免了竞争条件.

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

风格:http ://allendowney.com/sd/notes/notes11.txt的"处理异常情况"部分

避免竞争条件


引用的Avoiding Race Conditions(苹果开发支持)链接不支持您的答案.它仅涉及使用临时文件,这些文件包含设计不良的操作系统上的敏感信息,这些操作系统未通过受限权限正确地沙箱临时文件/目录.使用`try ... except`无论如何都无法解决*问题.
请添加更好的来源以支持您的陈述.

11> Aaron Hall..:

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

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

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

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

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

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

因为Python try到处使用,所以没有理由避免使用它的实现.

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

更长,更迂腐的答案

自Python 3.4起可用,使用新Path对象pathlib.请注意,这.exists不是很正确,因为目录不是文件(在unix意义上除了一切都是文件).

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

所以我们需要使用is_file:

>>> root.is_file()
False

这是帮助is_file:

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

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

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

默认情况下,NamedTemporaryFile在关闭时删除文件(并且当不存在更多引用时将自动关闭).

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

但是,如果你深入研究实现,你会看到它的is_file用途try:

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,您只需尝试读取您的文件,期望它在那里,如果没有,您将捕获异常并执行任何有意义的回退行为.

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

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

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

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

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

from contextlib import suppress
from pathlib import Path

用法:

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

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

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

尝试可能更容易:

from contextlib import contextmanager

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

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

ISFILE

import os
os.path.isfile(path)

来自文档:

os.path.isfile(path)

如果path是现有常规文件,则返回True.这是继符号链接,这样既islink()并且isfile()可以为相同的路径是正确的.

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

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

所有它正在使用给定的路径来查看它是否可以获取其中的统计信息,捕获OSError然后检查它是否是一个文件,如果它没有引发异常.

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

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

os.access

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

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

它也有同样的竞争条件问题isfile.来自文档:

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

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

写得更好:

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

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

对另一个答案的批评:

另一个答案说os.access:

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

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

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

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



12> loxsat..:
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.exists`返回true.这给出了误报.查看推荐"os.path.isfile"的其他答案.

13> Tom Fuller..:

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

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

在此输入图像描述

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

2016年,最佳方式仍在使用os.path.isfile:

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

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

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


请问:在python3中使用模块'pathlib'代替模块'os'进行此检查有什么好处?
`pathlib`是python的路径OOP解决方案.你可以用它做更多的事情.如果你只需要检查存在,那么优势就不那么大了.

15> chad..:

看起来似乎并没有在try/except之间存在有意义的功能差异isfile(),因此您应该使用哪一个有意义.

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

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

但是如果你只是想重命名一个文件,如果它存在,因此不需要打开它,那就行了

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

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

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

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

如果你需要文件锁定,那是另一回事.


在第三个例子中,我创建了一个名为`filepath`的链接,时间正确,而*BAM*,你覆盖了目标文件.你应该在`try ... except`块中执行`open(filepath,'wx')`来避免这个问题.
这个答案是对的.对于非文件的东西,例如目录,`os.path.exists`返回true.这给出了误报.查看推荐"os.path.isfile"的其他答案.

16> philberndt..:

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

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

输出将是:

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

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


最初的问题要求一个不使用`try`的解决方案
这个答案忽略了OP的观点.检查是否存在的文件与检查是否可以打开它不同.存在文件确实存在的情况但由于各种原因,您无法打开它.

17> Zizouz212..:

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

    尝试打开文件:

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

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

    如果它为False,它将在更高版本的Python中以无错的IOError或OSError停止执行.要捕获异常,必须使用try except子句.当然,你可以随时使用tryexcept`语句(感谢hsandt 让我思考):

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

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

    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对LBYP).如果您之后不打算打开文件,只检查其存在,那么您可以使用它.

    无论如何,这里:

    >>> 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)以便您可以确定您的问题.我希望它有所帮助!:)



18> Algebra..:

日期:2017年12月4日

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

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

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

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

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



19> zgoda..:

另外,os.access():

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

存在R_OK,W_OK以及X_OK用于测试权限的标志(doc).



20> bergercookie..:

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

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

UPDATE

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


这个答案是对的.对于非文件的东西,例如目录,`os.path.exists`返回true.这给出了误报.查看推荐"os.path.isfile"的其他答案.

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

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

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


OP询问如何检查文件是否存在.文件可能存在,但是您无法打开它.因此,使用打开文件作为代理来检查文件是否存在是不正确的:将具有错误否定.

22> durjoy..:

如果导入与NumPy已经用于其它用途,则没有必要导入其他库,例如pathlib,os,paths等.

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

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



23> Chris..:

你可以写一下布莱恩的建议try:.

from contextlib import suppress

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

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

from contextlib import contextmanager

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



24> Mike McKerns..:

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

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

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

而且文件......

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

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

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

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

>>>

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



25> Ali Hallaji..:
检查文件或目录是否存在

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

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

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

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

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

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

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



26> Marcel Wilso..:

添加一个更微小的变化,这在其他答案中没有完全反映出来.

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

根据Shahbaz的建议添加变体

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

根据Peter Wood的建议添加变体

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


`if(x)返回true; else返回false;`实际上只是`return x`.你的最后四行可以变成`return os.path.isfile(file_path)`.当我们在它的时候,整个函数可以简化为`return file_path和os.path.isfile(file_path)`.
`return file_path和os.path.isfile(file_path)`

27> Love and pea..:

这是Linux命令行环境的1行Python命令.我发现这非常好,因为我不是那么热的Bash家伙.

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

我希望这是有帮助的.


单行检查bash:`[ - f"$ {file}"] && echo"找到文件"|| echo"找不到文件"`(与`if [...]相同;然后......;否则......; fi`).

28> 小智..:

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

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


这个答案是对的.对于非文件的东西,例如目录,`os.path.exists`返回true.这给出了误报.查看推荐"os.path.isfile"的其他答案.

29> Inconnu..:

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

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

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

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

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

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



30> user3197473..:

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

open(inputFile, 'r')



31> Khaled.K..:
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)



32> Jesvin Jose..:
import os
path = /path/to/dir

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

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


这有两个方面是错误的:(1)`os.walk`查找目录树下的所有文件 - 如果用户想要检查`./FILE`,则他不太可能想要处理`./some/ sub/folder/FILE`作为匹配,你的解决方案; (2)与当前目录下面有许多文件的简单`os.path.isfile()`调用相比,你的解决方案效率很低.如果树中不存在匹配的filename-without-path,则代码将在返回false之前枚举树中的每个文件.

33> 小智..:

要检查文件是否存在,

from sys import argv

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


存在不区分文件和目录.os.path.isfile是检查文件是否存在的更好方法.
推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有