kni*_*nap 42 python scoping python-3.x
给出以下代码:
msg = "test"
try:
"a"[1]
except IndexError as msg:
print("Error happened")
print(msg)
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么这会导致Python 3中的以下输出?
Error happened
Traceback (most recent call last):
File "test.py", line 6, in <module>
print(msg)
NameError: name 'msg' is not defined
Run Code Online (Sandbox Code Playgroud)
Uku*_*kit 52
msgexcept子句中的范围msg与第一行的范围相同.
使用时分配异常
as target时,将在except子句的末尾清除它.这就好像Run Code Online (Sandbox Code Playgroud)except E as N: foo被翻译成
Run Code Online (Sandbox Code Playgroud)except E as N: try: foo finally: del N这意味着必须将异常分配给不同的名称才能在except子句之后引用它.异常被清除,因为附加了回溯,它们与堆栈帧形成一个引用循环,使该帧中的所有本地生存,直到下一次垃圾收集发生.
所以,你msg在异常处理程序中"覆盖",退出处理程序将删除该变量以清除回溯引用循环.
blh*_*ing 34
是的,一旦引发异常并msg分配了新的异常对象,原始对象就不再有引用,因此会被删除.一旦新的异常对象离开except块,它也会被删除.
您可以通过覆盖__del__对象的方法和分配给的异常来验证它msg:
class A:
def __del__(self):
print('object deleted')
class E(Exception):
def __del__(self):
print('exception deleted')
msg = A()
try:
raise E()
except E as msg:
print("Error happened")
Run Code Online (Sandbox Code Playgroud)
这输出:
object deleted
Error happened
exception deleted
NameError: name 'msg' is not defined
Run Code Online (Sandbox Code Playgroud)
异常块删除块末尾的catch变量,但它们没有自己的作用域.所以事件的顺序如下:
1)msg在本地范围内设置为某个字符串
2)msg设置为与1相同的本地范围内的IndexError对象
msg当异常块结束时,将从本地范围中删除3)
4)msg不再在本地范围内定义,因此访问它的尝试失败