检查文件是否可以用Python读取:try或if/else?

Bra*_*roy 21 python if-statement try-catch

我有以下代码:

import glob, os
for file in glob.glob("\\*.txt"):
    if os.access(file, os.R_OK):
        # Do something
    else:
        if not os.access(file, os.R_OK):
            print(file, "is not readable")
        else:
            print("Something went wrong with file/dir", file)
        break
Run Code Online (Sandbox Code Playgroud)

但我不完全确定这是否是正确的方法.使用trycatch错误更好吗?如果是这样,我如何尝试可读性?请注意break我的else语句.一旦无法读取文件,我想中止循环.

Tag*_*gar 24

更明确的方法来检查file实际上是否是文件而不是目录,并且它是可读的:

from os import access, R_OK
from os.path import isfile

file = "/some/path/to/file"

assert isfile(file) and access(file, R_OK), \
       "File {} doesn't exist or isn't readable".format(file)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果通过传递 -O 选项以优化模式执行 Python,则不会执行断言行 (https://docs.python.org/3/reference/simple_stmts.html#assert) (6认同)

Rob*_*obᵩ 13

对我来说,使用try-except与使用if-else获得的范围相同但没有可读性.异常的值是它们可以在调用树中的更高级别捕获.

移出一个级别,我们避免break声明:

import glob, os
try:
    for file in glob.glob("\\*.txt"):
        with open(file) as fp:
            # do something with file
except IOError:
    print("could not read", file)
Run Code Online (Sandbox Code Playgroud)

但真正的异常天才是代码消失的时候:

# Operate on several files
# SUCCESS: Returns None
# FAIL: Raises exception
def do_some_files():
    for file in glob.glob("\\*.txt"):
        with open(file) as fp:
            # do something with file
Run Code Online (Sandbox Code Playgroud)

现在调用程序负责在失败时显示有用的错误消息.我们已经完全免除了处理完故障的责任并进入了另一个领域.

事实上,人们可以将责任完全从我们的计划中转移到解释器中.在这种情况下,解释器将打印一些有用的错误消息并终止我们的程序.如果Python的默认消息是你的用户来说已经足够好,我建议不要检查错误可言.因此,您的原始脚本变为:

import glob, os
for file in glob.glob("\\*.txt"):
    # Do something
Run Code Online (Sandbox Code Playgroud)


ber*_*eal 5

在Python文化中,更常见的是请求宽恕,而不是许可,因此最好捕获异常:

for filename in glob.glob('*.txt'):
    try:
        with open(filename) as fp:
            # work with the file

    except IOError as err:
        print "Error reading the file {0}: {1}".format(filename, err)
        break
Run Code Online (Sandbox Code Playgroud)

这样你也可以避免任何双重检查或竞争条件.