是否在finally:stage中的except:stage中创建了变量?

时间:2015-03-11 20:57:49

标签: python python-3.x exception-handling try-catch-finally

我有一个try/except*n/finally代码块,我想知道如何正确执行以下操作:

try:
    some_function()
except exceptions.ExceptionA as e:
    self.logger.error("Error")
    subject = 'error A'
    message = 'Check error A'
except exceptions.ExceptionB as b:
    self.logger.error("Error")
    subject = 'error A'
    message = 'Check error A'
finally:
    self.publish(subject, message)
    sys.exit()

2 个答案:

答案 0 :(得分:2)

不,因为finally执行总是,而不仅仅是在引发和处理异常时。如果没有异常,或者您未处理异常,或者您在return之外使用continuebreaktry,则会执行此操作{1}}等等。

如果已处理异常,那么except套件中绑定的名称将在finally套件执行时保持设置,但您需要设置它们至少要发送哨兵值,以免在没有引起此类例外的情况下避免NameErrorUnboundLocal例外:

subject = message = None
try:
    some_function()
except exceptions.ExceptionA as e:
    self.logger.error("Error")
    subject = 'error A'
    message = 'Check error A'
except exceptions.ExceptionB as b:
    self.logger.error("Error")
    subject = 'error A'
    message = 'Check error A'
finally:
    # message and subject *can* be bound to None now
    self.publish(subject, message)
    sys.exit()

如果您想要执行代码 ,如果引发并处理了异常,则您必须明确为每个except套件执行此操作。在这种情况下你不能使用finally,而不是没有额外的检查(例如你可以在subject is not None上登机)。

答案 1 :(得分:1)

是的,您可以在except块中使用finally中的变量,因为Python中的变量具有函数范围。

In [1]: try:
   ...:     raise ValueError()
   ...: except:
   ...:     x = 1
   ...: finally:
   ...:     print(x)
   ...:     
1

但是你必须确保在所有代码路径中初始化变量。

try:
    pass
except:
    x = 1
finally:
    print(x) # NameError

通常,您将首先初始化变量:

x = None
try:
    ...
except:
    x = ...
finally:
    ... safe to use x here ...