请考虑以下代码:
import shutil
import time
t = time.time()
exception = None
while time.time() < (t + 10.0):
try:
shutil.rmtree('/path-to-non-existent-directory')
break
except OSError as exception:
pass
time.sleep(0.1)
else:
if exception:
raise exception
在Python 2.7中,此代码完全有效,但在Python 3.7中,我收到以下警告:
Local variable exception might be referenced before assignment
在else
子句中。
有人知道在Python 3.7中运行时此代码段有什么问题吗?
答案 0 :(得分:1)
在Python 3中,为解决由于引入__traceback__
属性而引起的循环引用问题,在except
块的末尾会自动删除一个except
目标。就像您写过一样
except OSError as exception:
pass
del exception
这在PEP 3110中有记录。
如果要保留异常对象,则应将其保存到第二个变量:
except OSError as exception:
saved_exception = exception
exception
仍将被删除,但是在saved_exception
块结束之后,您可以使用except
检查异常对象。
答案 1 :(得分:0)
Python是一种块作用域语言,您不能在定义它的块之外引用变量,也不能在更新了该变量的块之外使用新值。
换句话说,您不能在exception
块之外引用except
变量的错误数据,如果尝试这样做,则exception
变量的值将是None
(在顶层设置)。
尝试将else
块的内容移动到except
块,并摆脱exception = None
和if exception
,就像这样:
timer = Timer(10.0)
while timer.alive:
try:
shutil.rmtree(cls.workspace)
break
except OSError as exception:
raise exception
time.sleep(0.1)
如果您不希望出现致命错误,则可以使用print()
函数而不是raise
关键字:
timer = Timer(10.0)
while timer.alive:
try:
shutil.rmtree(cls.workspace)
break
except OSError as exception:
print(exception)
time.sleep(0.1)
这是另一个示例(不起作用):
def hello():
message = "Hello World"
print(message)
因为它会引发以下错误:
NameError: name 'message' is not defined
注意::建议不要调用您的异常exception
,因为有一个名为Exception
的错误类,这样做以后可能会引起混乱。
祝你好运。