В идеале вы должны использовать python с оператором для очистки в блоке try ... except
, который будет выглядеть примерно так:
class Something(object):
def __enter__(self):
print "Entering"
def __exit__(self, t, v, tr):
print "cleanup - always runs"
raise Exception("Exception occurred during __exit__")
try:
with Something() as something:
raise Exception("Exception occurred!")
except Exception, e:
print e
import traceback
traceback.print_exc(e)
print "Exited normally!"
Когда я запускаю это, он печатает:
Entering
cleanup - always runs
Exception occurred during __exit__
Traceback (most recent call last):
File "s3.py", line 11, in <module>
raise Exception("Exception occurred!")
File "s3.py", line 7, in __exit__
raise Exception("Exception occurred during __exit__")
Exception: Exception occurred during __exit__
Exited normally!
Обратите внимание, что любое исключение прекратит работу программы и может быть рассмотрено в инструкции except
.
Редактировать: В соответствии с документацией с оператором, связанной с вышеупомянутым, метод __exit__()
должен вызывать исключение только в случае ошибки внутри __exit__()
, то есть он не должен повторно вызывать в него передано исключение.
Это проблема, если и код в операторе with
, и метод __exit__()
вызывают исключение. В этом случае исключение, которое попадает в условие исключения, является исключением, возникшим в __exit__()
. Если вы хотите, чтобы тот, который был поднят в утверждении with, вы можете сделать что-то вроде этого:
class Something(object):
def __enter__(self):
print "Entering"
def __exit__(self, t, v, tr):
print "cleanup - always runs"
try:
raise Exception("Exception occurred during __exit__")
except Exception, e:
if (t, v, tr) != (None, None, None):
# __exit__ called with an existing exception
return False
else:
# __exit__ called with NO existing exception
raise
try:
with Something() as something:
raise Exception("Exception occurred!")
pass
except Exception, e:
print e
traceback.print_exc(e)
raise
print "Exited normally!"
Это печатает:
Entering
cleanup - always runs
Exception occurred!
Traceback (most recent call last):
File "s2.py", line 22, in <module>
raise Exception("Exception occurred!")
Exception: Exception occurred!
Traceback (most recent call last):
File "s2.py", line 22, in <module>
raise Exception("Exception occurred!")
Exception: Exception occurred!