Can someone please help me understand what is happening here. I have some understanding on how scope of variables work in python.
When this code runs, I get an error:
rec = True
try:
print("outer try")
raise Exception("outer exception")
except Exception as msg:
try:
rec = True
print("inner try")
raise Exception("inner exception")
except Exception as msg:
rec = False
print(str(msg))
if rec == False:
print(str(msg))
outer try
inner try
inner exception
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
<ipython-input-2-6ce9b26112ed> in <module>
5 print("outer try")
----> 6 raise Exception("outer exception")
7 except Exception as msg:
Exception: outer exception
During handling of the above exception, another exception occurred:
NameError Traceback (most recent call last)
<ipython-input-2-6ce9b26112ed> in <module>
15
16 if rec == False:
---> 17 print(str(msg))
NameError: name 'msg' is not defined
rec = True
try:
print("outer try")
raise Exception("outer exception")
except Exception as outer_msg:
try:
rec = True
print("inner try")
raise Exception("inner exception")
except Exception as msg:
rec = False
print(str(msg))
if rec == False:
print(str(outer_msg))
Output:
outer try
inner try
inner exception
outer exception
Is this error related to "Scope of Variables" or "Closure"? If anyone has a link to a detailed explanation of this in python can you please help.
The block beginning
except Exception as msg:
creates the msg
variable at the start of the block, and deletes it at the end of the block. The msg
variable that existed already is in the same scope and has the same name, so it is overwritten and then deleted.
You need to use separate names for your two exceptions if you want to track both, because they are in the same scope.
See https://docs.python.org/3/reference/compound_stmts.html#the-try-statement which says:
When an exception has been assigned using
as target
, it is cleared at the end of the except clause. This is as ifexcept E as N: foo
was translated to
except E as N: try: foo finally: del N