如何检查文件是否存在,而不使用try
语句?
如何在没有异常的情况下检查文件是否存在?
如果你检查的原因是这样你可以做类似if file_exists: open_it()
的事情,那么在尝试打开它时使用try
会更安全。 检查,然后打开风险文件被删除或移动或之间的东西,当您检查,当您尝试打开它。
如果您不打算立即打开文件,可以使用os.path.isfile
如果path是现有的常规文件,则返回
True
。 这遵循符号链接,因此对于相同的路径,islink()和isfile()都可以为true。
import os.path
os.path.isfile(fname)
如果你需要确定它是一个文件。
从Python3.4开始,pathlib
模块提供了面向对象的方法(在Python2.7中反向移植到pathlib2
):
from pathlib import Path
my_file = Path("/path/to/file")
if my_file.is_file():
# file exists
要检查目录,请执行:
if my_file.is_dir():
# directory exists
要检查Path
对象是否独立于它是文件还是目录存在,请使用exists()
:
if my_file.exists():
# path exists
您也可以在try
块中使用try
:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
所有回答
与isfile()
不同,exists()
将为目录返回True
。 因此,根据您是否只想要普通文件或目录,您将使用isfile()
或exists()
。 下面是一些简单的REPL输出:
>>> os.path.isfile("/etc/password.txt")
True
>>> os.path.isfile("/etc")
False
>>> os.path.isfile("/does/not/exist")
False
>>> os.path.exists("/etc/password.txt")
True
>>> os.path.exists("/etc")
True
>>> os.path.exists("/does/not/exist")
False
使用os.path.isfile()
withos.access()
:
import os
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")
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
虽然几乎所有可能的方式都已在(至少一个)现有的答案中列出(例如Python3.4特定的东西被添加),但我会尝试将所有内容组合在一起。
注意:我要发布的每一段Python标准库代码,都属于版本3.5.3。
问题陈述:
- 检查文件(argue:也文件夹("特殊"文件)?)存在
- 不要使用尝试/除了/其他/最后块
可能的解决方案:
[Python3]:os。路径。exists(path)(也检查其他函数家族成员,如
os.path.isfile
,os.path.isdir
,os.path.lexists
略有不同的行为)os.path.exists(path)
返回
True
如果path引用现有路径或打开的文件描述符。 对于损坏的符号链接返回False
。 在某些平台上,如果未授予执行os的权限,此函数可能会返回False
。请求的文件上的stat(),即使路径物理存在。一切都很好,但如果遵循导入树:
os.path
-posixpath.py(ntpath.py)genericpath.py,行~#20+
def exists(path): """Test whether a path exists. Returns False for broken symbolic links""" try: st = os.stat(path) except os.error: return False return True
它只是一个尝试/除了块围绕[Python3]:os。stat(path,*,dir_fd=None,follow_symlinks=True)。 所以,你的代码是尝试/除了免费,但在框架中较低,有(至少)一个这样的块。 这也适用于其他功能(包括
os.path.isfile
)。- 这是一种更好的处理路径的方式(以及更多的pythonic),但是
在引擎盖下,它确实完全同样的事情(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
[Python3]:带有语句上下文管理器。 任一:
创建一个:
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
行为(请注意,这只是为了演示目的,donot尝试为production编写此类代码):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
使用[Python3]:contextlib。抑制(*异常)-这是专门为选择性抑制异常而设计的
但是,它们似乎是try/除了/else/最后块,as[Python3]:带有语句的声明:文件系统遍历函数(并在结果中搜索匹配项)
[Python3]:os。listdir(path='.')(或[Python3]:os.scandir(path='.')在Python v3.5+,backport:[PyPI]:scandir)
引擎盖下,两者都使用:
- Nix:[man7]:OPENDIR(3)/[man7]:READDIR(3)/[man7]:CLOSEDIR(3)
- Win:[Ms.Docs]:FindFirstFileW函数/[MS.Docs]:FindNextFileW函数/[MS.Docs]:FindClose函数
via[GitHub]:python/cpython-(master)cpython/Modules/posixmodule。c
使用scandir()而不是listdir()可以显着提高同样需要文件类型或文件属性信息的代码的性能,因为os。如果操作系统在扫描目录时提供此信息,则DirEntry对象会公开此信息。 所有操作系统。DirEntry方法可能会执行系统调用,但is_dir()和is_file()通常只需要系统调用符号链接;os。迪拉特里。Stat()在Unix上总是需要一个系统调用,但在Windows上只需要一个符号链接。
- [Python3]:os。walk(top,topdown=True,onerror=None,followlinks=False)
- 它使用
os.listdir
(os.scandir
可用时)
- 它使用
- [Python3]:glob。iglob(pathname,*,recursive=False)(或其前身:
glob.glob
)- 本身似乎不是遍历函数(至少在某些情况下),但它仍然使用
os.listdir
- 本身似乎不是遍历函数(至少在某些情况下),但它仍然使用
由于这些迭代文件夹,(在大多数情况下)它们对我们的问题效率低下(有例外,如非通配符globbing-正如@ShadowRanger指出的那样),所以我不打算坚持它们。 更不用说在某些情况下,可能需要文件名处理。[Python3]:os。access(path,mode,*,dir_fd=None,effective_ids=False,follow_symlinks=True)其行为接近
os.path.exists
(实际上它更宽,主要是因为2nd参数)- 用户权限可能会限制文件的"可见性",如doc所述:
。..测试调用用户是否具有对路径的指定访问权限。 mode应该是F_OK来测试path的存在。..
os.access("/tmp", os.F_OK)
由于我也在C中工作,我也使用这种方法,因为在引擎盖下,它调用nativeAPIs(再次,通过"${PYTHON_SRC_DIR}/Modules/posixmodule。c"),但它也为可能的用户错误打开了一个大门,并且它不像其他变体那样Pythonic。 所以,正如@AaronHall正确指出的那样,除非你知道自己在做什么,否则不要使用它:
- Nix:[man7]:ACCESS(2)(!!! 注意关于安全漏洞它的用法可能会引入的注意事项!!!)
- Win:[Ms.Docs]:GetFileAttributesW函数
注意:调用nativeAPIs也可以通过[Python3]:ctypes-Python的外部函数库,但在大多数情况下它更复杂。
(Winspecific):自vcruntime*(msvcr*)。dll导出a[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,以便相同的代码在Python3和Python2上工作(尽管它们之间存在unicode相关差异)
- 虽然这针对一个非常具体的领域,但在之前的任何答案中都没有提到
该Lnx(Ubtu(16x64))对应以及: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,则返回的句柄为main 程序。 当给出dlsym()时,此句柄会导致搜索 主程序中的符号,然后是加载在 程序启动,然后由dlopen()加载的所有共享对象与 标志RTLD_GLOBAL。
- 主(当前)程序(python)与libc链接,因此它的符号(包括访问)将被加载
- 这必须小心处理,因为像main,Py_Main和(所有)其他函数都是可用的;调用它们可能会产生灾难性的影响(对当前程序)
- 这也不适用于Win(但这并不是什么大不了的事情,因为msvcrt。dll位于"%SystemRoot%\System32"默认情况下位于%PATH%中)。 我想进一步研究并在Win上复制这种行为(并提交补丁),但事实证明,[MS.Docs]:GetProcAddress function只"看到"导出的符号,所以除非有人将主可执行文件中的函数声明为
__declspec(dllexport)
(),主程序是可加载的,但几乎无法使用
- 用户权限可能会限制文件的"可见性",如doc所述:
安装一些具有文件系统功能的第三方模块
最有可能的是,将依赖于上述方式之一(可能有轻微的自定义)。
一个例子是(同样,Win特定)[GitHub]:mhammond/pywin32-Python for Windows(pywin32)Extensions,它是Pythonwrapper overWINAPIs.但是,由于这更像是一种解决方法,我在这里停下来。
另一个(跛脚)解决方法(gainarie)是(正如我喜欢称之为的那样)sysadmin方法:使用Python作为包装器来执行shell命令
赢:
(py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe\" > nul 2>&1'))" 0 (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))" 1
Nix(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
底线:
- Dousetry/except/else/finallyblocks,因为它们可以防止你遇到一系列令人讨厌的问题。 我能想到的一个反例是性能:这样的块是昂贵的,所以尽量不要将它们放在应该每秒运行数十万次的代码中(但是由于(在大多数情况下)它涉及磁盘访问,
尾音:
- 我会尽量保持最新,欢迎任何建议,我会将任何有用的东西纳入答案
Python3.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模块有很多很酷的东西:方便的globbing,检查文件的所有者,更容易的路径连接等。 值得一试。 如果您使用的是较旧的Python(版本2.6或更高版本),您仍然可以使用pip安装pathlib:
# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2
然后按如下方式导入:
# Older Python versions
import pathlib2 as pathlib
这是检查文件是否存在的最简单方法。 只是,因为文件在您检查时存在,不保证在您需要打开它时它会在那里。
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")
如何在不使用try语句的情况下使用Python检查文件是否存在?
从Python3.4开始,导入并实例化一个带有文件名的
Path
对象,并检查
is_file
方法(请注意,对于指向常规文件的符号链接,这也返回True):
>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
如果你在Python2上,你可以从pypi backport pathlib模块,
pathlib2
,或者从
os检查
模块:
isfile
。路径
>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
现在上面可能是这里最好的务实的直接答案,但是有一个竞争条件的可能性(取决于你试图完成的事情),以及底层实现使用a
try
的事实,但是Python在其实
因为Python在任何地方都使用
try
,所以没有理由避免使用它的实现。
但这个答案的其余部分试图考虑这些警告。
更长,更迂腐的答案
从Python3.4开始可用,在
pathlib
中使用新的
Path
对象。 请注意,
.exists
并不完全正确,因为目录不是文件(除了在unix意义上
everything
是一个文件)。
>>> 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
,您只需尝试读取文件,期望它在那里,如果没有,则捕获异常并执行任何有意义的回退行为。
如果您想在尝试读取文件之前检查文件是否存在,并且您可能正在删除它,然后您可能正在使用多个线程或进程,或者另一个程序知道该文件并可能删除它-如果您检查它是否存在,那么您将冒着 竞争条件 的风险,因为您将在 条件 (其存在)更改之前打开它。
竞争条件很难调试,因为有一个非常小的窗口,它们可能导致程序失败。
但是如果这是你的动机,你
可以
通过使用
suppress
上下文管理器来获取
try
语句的值。
在没有try语句的情况下避免竞争条件:
suppress
Python3.4为我们提供了
suppress
上下文管理器(以前是
ignore
上下文管理器),它在语义上以更少的行完成完全相同的事情,同时(至少在表面上)满足原
from contextlib import suppress
from pathlib import Path
使用方法:
>>> with suppress(OSError), Path('doesnotexist').open() as f:
... for line in f:
... print(line)
...
>>>
>>> with suppress(OSError):
... Path('doesnotexist').unlink()
...
>>>
对于早期的蟒蛇,你可以滚动你自己的
suppress
,但没有a
try
会比with更冗长。 我相信
这实际上是唯一一个在Python
中任何级别都不使用
try
的答案,可以在Python3.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。访问
可用于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
,允许所有异常(包括
KeyboardInterrupt
和
SystemExit
!)默默通过,这是隐藏bug的好方法。
这似乎鼓励用户采用不良做法。
更喜欢try语句。 它被认为是更好的风格和避免比赛条件。
别相信我的话. 这一理论有很多支持。 这里有一对夫妇:
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
。
2016年最好的办法还是用os.path.isfile
:
>>> os.path.isfile('/path/to/some/file.txt')
或者在Python3中你可以使用pathlib
:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
...
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'
如果你需要文件锁定,那就另当别论了。
TL;DR
答案是:pathlib
模块--用一行代码--
Pathlib可能是几乎所有文件操作的最现代和最方便的方式。 对于文件或文件夹的存在,一行代码就足够了。
from pathlib import Path
if Path("myfile.txt").exists(): # works for both file and folders
# do your cool stuff...
pathlib
模块是在Python 3.4
中引入的,所以你需要有Python3.4+,这个lib使你在处理文件和文件夹时的生活变得更加容易,而且它非常好用,这里有更多关于它的文档(https://docs.python.org/3/library/pathlib.html)。
顺便说一句,如果你要重用路径,那么最好将其分配给一个变量
因此将成为
from pathlib import Path
p = Path("loc/of/myfile.txt")
if p.exists(): # works for both file and folders
# do stuffs...
#reuse 'p' if needed.
你可以试试这个(更安全):
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))
输出将是:
([Errno2]没有这样的文件或目录: ""随便吧。txt')
然后,根据结果,您的程序可以从那里继续运行,或者如果您愿意,您可以编写代码来停止它。
日期:2017-12-04
其他答案中列出了每个可能的解决方案。
检查文件是否存在的直观且有争议的方法如下:
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')
我做了一个详尽的cheatsheet供您参考:
#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']}
虽然我总是建议使用try
和except
语句,但这里有一些可能性(我个人最喜欢使用os.access
):
尝试打开文件:
打开文件将始终验证文件的存在。 你可以像这样做一个函数:
def File_Existence(filepath): f = open(filepath) return True
如果它是False,它将使用unhanded IOError停止执行 或更高版本的Python中的OSError。 捕获异常, 您必须使用try except子句。 当然,你可以随时 使用
try
except'这样的语句(感谢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
,它将检查路径的存在。 但是,使用这将创建一个安全漏洞,因为有人可以使用检查权限和打开文件之间的时间来攻击您的文件。 您应该直接打开文件,而不是检查其权限。 (EAFPvsLBYP)。 如果你之后不打算打开文件,只检查它的存在,那么你可以使用这个。无论如何,在这里:
>>> import os >>> os.access("/is/a/file.txt", os.F_OK) True
我还应该提到,有两种方法,你将无法验证文件的存在。 问题将是permission denied
或no such file or directory
。 如果你抓住了一个IOError
,设置IOError as e
(就像我的第一个选项一样),然后输入print(e.args)
,这样你就可以有希望地确定你的问题。 我希望它有帮助! :)
最简单的方法是
import os
if os.path.exists(FILE):
# file exists
pass
else:
# file does not exists
pass
来自os库,而文件是相对路径。 在Windows中,这可能或很多都不起作用,您可能必须通过执行os.path.exists(os.path.join(os.path.abspath('./'), FILE))
来使用绝对路径,其中FILE仍然是相对路径加上文件名
另外,os.access()
:
if os.access("myfile", os.R_OK):
with open("myfile") as fp:
return fp.read()
是R_OK
、W_OK
和X_OK
测试权限的标志(doc)。
如果该文件用于打开,则可以使用以下技术之一:
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!')
更新
只是为了避免混淆,并根据我得到的答案,current answer找到了一个文件或一个给定名称的目录。
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异常将是 如果文件存在但用户没有读取权限,则引发。
如果您已经将NumPy导入其他用途,则无需导入其他库,例如pathlib
, os
, paths
, 等。
import numpy as np
np.DataSource().exists("path/to/your/file")
这将根据其存在返回true或false。
你可以在没有try:
的情况下写出布莱恩的建议。
from contextlib import suppress
with suppress(IOError), open('filename'):
process()
suppress
是Python3.4的一部分。 在旧版本中,您可以快速编写自己的压制:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
检查文件或目录是否存在
你可以遵循这三种方式:
注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
方法(包含在Python3+中,可与python2的pip一起安装)
from pathlib import Path
Path(filename).exists()
添加一个轻微的变化,这并不完全反映在其他答案中。
这将处理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):
我是一个已经存在了大约10年的软件包的作者,它有一个直接解决这个问题的函数。 基本上,如果您在非Windows系统上,它使用Popen
访问find
。 但是,如果您在Windows上,它会使用高效的文件系统步行器复制find
。
代码本身不使用try
块......除非确定操作系统,从而将您引导到"Unix"风格find
或手动builltfind
。 定时测试表明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
你有
os.path.exists
功能:这对文件和目录都返回
True
,但您可以改为使用测试它是否是一个文件。 它遵循符号链接。