如何在不使用文件的情况下查看文件是否存在 try
声明?
如何在不使用文件的情况下查看文件是否存在 try
声明?
如果您检查的原因是这样,您可以做类似的事情 if file_exists: open_it()
,使用它更安全 try
试图打开它。检查然后打开风险,删除或移动文件或检查时以及尝试打开文件时。
如果您不打算立即打开文件,则可以使用 os.path.isfile
返回
True
如果path是现有的常规文件。这遵循符号链接,所以两者 islink() 和 ISFILE() 对于同一条路径可以是真的。
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()
在一个 try
块:
try:
my_abs_path = my_file.resolve()
except FileNotFoundError:
# doesn't exist
else:
# exists
如果您检查的原因是这样,您可以做类似的事情 if file_exists: open_it()
,使用它更安全 try
试图打开它。检查然后打开风险,删除或移动文件或检查时以及尝试打开文件时。
如果您不打算立即打开文件,则可以使用 os.path.isfile
返回
True
如果path是现有的常规文件。这遵循符号链接,所以两者 islink() 和 ISFILE() 对于同一条路径可以是真的。
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()
在一个 try
块:
try:
my_abs_path = my_file.resolve()
except FileNotFoundError:
# doesn't exist
else:
# exists
你有 os.path.exists
功能:
import os.path
os.path.exists(file_path)
这回来了 True
对于文件和目录,但您可以改为使用
os.path.isfile(file_name)
测试它是否是一个特定的文件。它遵循符号链接。
不像 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
import os.path
if os.path.isfile(filepath):
使用 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"
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
这是检查文件是否存在的最简单方法。只是 因为 检查时存在的文件没有 保证 当你需要打开它时它会在那里。
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")
2017/12/22:
尽管几乎所有可能的方式都列在(至少一个)现有答案中(例如 Python 3.4 添加了特定的东西),我会尝试将所有内容组合在一起。
注意:每一块 蟒蛇 我要发布的标准库代码属于版本 3.5.3 (doc引用是版本 3 具体)。
问题陈述:
try
/ except
/ else
/ finally
块可能的解决方案:
[Python]: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,行 〜#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
它只是一个 try/except
挡住了 [Python]:os。统计(path,*,dir_fd = None,follow_symlinks = True)。所以,你的代码是 try/except
免费,但在框架中较低(至少) 一 这样的块。这也适用于其他功能(包含 os.path.isfile
)。
1.1。 [Python]:pathlib.Path。is_file()
在引擎盖下,确实如此 究竟 一样的东西 (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
创建一个:
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 ...)
它的用法 - 我会复制它 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]:contextlib。压制(*例外) - 是的 特别 旨在有选择地抑制异常
但是,它们似乎是包装纸 try/except/else/finally
块,如 [Python]:The 同 声明 状态:
文件系统遍历函数(并搜索匹配项的结果)
[Python]:os。listdir同时(路径= '') (要么 [Python]:os。SCANDIR(路径= '') 上 Python v3.5+)
运用 SCANDIR() 代替 listdir同时() 可以显着提高还需要文件类型或文件属性信息的代码的性能,因为 os.DirEntry 如果操作系统在扫描目录时提供此信息,则会显示此信息。所有 os.DirEntry 方法可以执行系统调用,但是 is_dir() 和 is_file() 通常只需要系统调用符号链接; os.DirEntry.stat() 总是需要在Unix上进行系统调用,但在Windows上只需要一个符号链接。
os.listdir
(os.scandir
有空的时候)os.listdir
由于这些迭代文件夹,(在大多数情况下)它们对我们的问题是低效的(有例外,如非通配符 glob的bing - 正如@ShadowRanger指出的那样,所以我不会坚持他们。更不用说在某些情况下,可能需要文件名处理。
[Python]:os。访问(path,mode,*,dir_fd = None,effective_ids = False,follow_symlinks = True) 他的行为很接近 os.path.exists
(实际上它更宽,主要是因为2ND 论据)
...测试调用用户是否具有指定的访问权限 路径。 模式 应该 F_OK 测试路径的存在...
os.access("/tmp", os.F_OK)
因为我也在工作 C,我也使用这种方法,因为在引擎盖下,它调用 本地人 API小号 (再次,通过 “$ {} PYTHON_SRC_DIR /Modules/posixmodule.c”),但它也打开了一扇门 用户错误,而不是 蟒蛇ic作为其他变种。所以,正如@AaronHall正确指出的那样,除非你知道你在做什么,否则不要使用它:
注意:调用原生 APIs也可以通过 [蟒蛇]: ctypes的 - Python的外部函数库,但在大多数情况下,它更复杂。
(赢得 具体):自从 msvcr *(vcruntime *)出口一个 [MSDN]:_ access,_waccess 函数族也是,这是一个例子:
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import os, ctypes >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe", os.F_OK) 0 >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\___cmd.exe", os.F_OK) -1
笔记:
os.F_OK
在通话中,但这只是为了清晰(它的价值是 0)_waccess
以便相同的代码可以工作 Python3 和 Python2 (尽管 统一 它们之间的相关差异)
该 LNX (Ubtu(16 x64))同行:
Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os, ctypes >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK) 0 >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp1", os.F_OK) -1
笔记:
而是硬编码 的libc的路径(“/lib/x86_64-linux-gnu/libc.so.6”)可能(并且很可能会)在各系统之间变化, None
(或空字符串)可以传递给 CDLL
构造函数(ctypes.CDLL(None).access(b"/tmp", os.F_OK)
)。根据 [男人]:DLOPEN(3):
如果 文件名 为NULL,则返回的句柄为main 程序。当给予 对dlsym(),此句柄导致搜索a 主程序中的符号,后跟加载的所有共享对象 程序启动,然后加载所有共享对象 的dlopen() 国旗 RTLD_GLOBAL。
access
)将被加载main
, Py_Main
和(所有)其他人可用;打电话给他们可能会产生灾难性后果(在当前的节目中)__declspec(dllexport)
(为什么在地球上 定期 人会这样做吗?),主程序是可加载的,但几乎无法使用安装一些3RD 具有文件系统功能的派对模块
最有可能的是,将依赖于上述方法之一(可能需要轻微的自定义)。
一个例子是(再次, 赢得 具体) [GitHub]:用于Windows的Python(pywin32)扩展,这是一个 蟒蛇 包装 WINAPI秒。
但是,由于这更像是一种解决方法,我在这里停下来。
另一个(跛脚)解决方法(gainarie)(就像我喜欢称之为) 系统管理员 方法:使用 蟒蛇 作为执行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
底线:
try
/ except
/ else
/ finally
块,因为它们可以防止你遇到一系列令人讨厌的问题。我能想到的一个反例是性能:这样的块是昂贵的,所以尽量不要将它们放在它应该每秒运行数十万次的代码中(但是因为(在大多数情况下)它涉及磁盘访问,事实并非如此)。最后的注释: