使用时如何关闭文件和try..except?

时间:2017-12-22 10:22:51

标签: python

我写这个例子是为了告诉我自己在发生异常时没有运行__exit__

class A(object):
    def __enter__(self):
        print('enter')
    def __exit__(self):
        print('exit')
try:
    with A() as a:
        raise RunTimeError()
except Exception as e:
    print('except')

输出:

enter
except

那就是说,使用with语句并捕获异常的正确方法是什么,同时确保最终运行__exit__? 谢谢!

1 个答案:

答案 0 :(得分:3)

__exit__函数被称为,无论with正文是否引发错误。您的函数需要有其他参数exc_type(异常的类型),exc_value(异常对象)和traceback(生成的回溯)。

如果with正文提出Error,则三个参数为None。如果出现错误,则采用上述值。

但是你可以关闭一个文件,无论是否有错误,然后再处理错误。

所以我们可以在这里实现它:例如:

class A(object):
    def __enter__(self):
        self.file = open('some_file.txt')
        return self.file

    def __exit__(self, exc_type, exc_value, traceback):
        print(('exit', exc_type, exc_value, traceback))
        # close the file, regardless of exceptions
        self.file.close()
        return False  # silence the exception?

如果我们现在写下这样的话:

with A():
    raise Exception

我们将获得例外,__exit__函数将打印:

('exit', <class 'Exception'>, Exception(), <traceback object at 0x7fc512c924c8>)

我们可以检查异常类,异常值和回溯,并相应地处理。例如,基于异常,我们可能决定关闭文件,发送错误报告,中止SQL事务。

__exit__函数也有一个返回值(如果没有指定,Python函数返回None)。如果__exit__函数返回一个真实性 True的对象,它将压制异常:异常不会从{{{{ 1}}阻止。否则它将被提升出with块。例如,在我们的示例中,我们仍然收到异常。

with

如果我们现在打电话:

class SilenceExceptions(object):
    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_value, traceback):
        return True  # silence ALL exceptions

我们不会看到异常,因为它是with SilenceExceptions(): raise Error 函数中的“ catched ”。