在Python中使用异常和文件时进行清理

2024-04-28 12:01:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经学了几天python了,我正在努力学习它的“精神”。 我从C/C++ +java/Perl学校开始学习,我理解Python不是C(完全),这就是为什么我要努力理解精神,以最大限度地利用它(到目前为止很难)…在

我的问题特别集中在异常处理和清理上: 本文末尾的代码是为了模拟一个相当常见的打开/解析文件的情况,在这种情况下,您需要关闭文件以防出现错误。。。在

我看到的大多数示例都使用try语句的“else”子句来关闭文件。。。在我意识到错误可能是由于

  • 开口本身(在这种情况下 没有必要关闭not 打开的文件)
  • 解析(其中 如果需要关闭文件)

这里的陷阱是,如果您使用try bloc的“else”子句,那么在解析过程中发生错误时,文件永远不会关闭! 另一方面,使用“finally”子句会导致额外的必要检查,因为如果在打开过程中发生错误,file_desc变量可能不存在(请参阅下面代码中的注释)。。。在

这个额外的检查是低效的,而且充满了垃圾,因为任何合理的程序都可能包含数百个符号,解析dir()的结果是一件痛苦的事。。。更不用说这种说法缺乏可读性。。。在

大多数其他语言都允许变量定义,这样可以节省时间。。。但是在python中,一切似乎都是隐含的。。。在

通常,只需声明一个file_desc变量,然后对每个任务使用多个try/catch bloc。。。一个用于打开,一个用于解析,最后一个用于关闭()。。。不需要筑巢。。。我不知道如何声明变量。。。所以我被困在问题的开始!在

那么这里的Python精神是什么???在

  • 将打开/解析分成两种不同的方法?怎样?在
  • 使用某种嵌套的try/except子句???怎样?在
  • 也许有一种方法可以声明file_desc变量,然后就不需要额外的检查了。。。有可能吗???想要的???在
  • close()语句呢???如果它引发错误怎么办?在

谢谢你的提示。。。下面是示例代码:

class FormatError(Exception):
    def __init__(self, message):
        self.strerror = message
    def __str__(self):
        return repr(message)


file_name = raw_input("Input a filename please: ")
try:
    file_desc = open(file_name, 'r')
    # read the file...
    while True:
        current_line = file_desc.readline()
        if not current_line: break
        print current_line.rstrip("\n")
    # lets simulate some parsing error...
    raise FormatError("oops... the file format is wrong...")
except FormatError as format_error:
    print "The file {0} is invalid: {1}".format(file_name, format_error.strerror)
except IOError as io_error:
    print "The file {0} could not be read: {1}".format(file_name, io_error.strerror)
else:
    file_desc.close()
# finally:
#     if 'file_desc' in dir() and not file_desc.closed:
#        file_desc.close()

if 'file_desc' in dir():
    print "The file exists and closed={0}".format(file_desc.closed)
else:
    print "The file has never been defined..."

Tags: 文件the代码nameformat精神错误not
3条回答

请注意:您可以始终声明一个变量,然后它会变成这样:

file_desc = None
try:
    file_desc = open(file_name, 'r')
except IOError, err:
    pass
finally:
    if file_desc:
        close(file_desc)

当然,如果您使用的是较新版本的Python,那么使用context manager的构造要好得多;但是,我想指出如何在Python中一般地处理异常和变量范围。在

在Python2.5中,有一个with命令,它简化了您正在使用的一些东西。阅读更多信息here。以下是代码的转换版本:

class FormatError(Exception):
    def __init__(self, message):
        self.strerror = message
    def __str__(self):
        return repr(message)


file_name = raw_input("Input a filename please: ")
with open(file_name, 'r') as file_desc:
    try:
        # read the file...
        while True:
            current_line = file_desc.readline()
            if not current_line: break
            print current_line.rstrip("\n")
        # lets simulate some parsing error...
        raise FormatError("oops... the file format is wrong...")
    except FormatError as format_error:
        print "The file {0} is invalid: {1}".format(file_name, format_error.strerror)
    except IOError as io_error:
        print "The file {0} could not be read: {1}".format(file_name, io_error.strerror)

if 'file_desc' in dir():
    print "The file exists and closed={0}".format(file_desc.closed)
else:
    print "The file has never been defined..."

处理这个问题最简单的方法是使用Python2.5+中的文件对象是context managers。您可以使用^{}语句来输入上下文;当退出这个with作用域时,上下文管理器的__exit__方法将被自动调用。文件对象的上下文管理会自动关闭文件。在

try:
    with file("hello.txt") as input_file:
        for line in input_file:
            if "hello" not in line:
                 raise ValueError("Every line must contain 'hello'!")
except IOError:
    print "Damnit, couldn't open the file."
except:
    raise
else:
    print "Everything went fine!"

开放的你好.txt句柄将自动关闭,with范围内的异常将传播到外部。在

相关问题 更多 >