I'm trying to declare two functions within exec statement in python. Let's call them f1() and f2().
I've found out that when exec is invoked inside of some function, then f2() has no visibility of f1(). However this doesn't happen when exec and function call are placed in global code.
# Case 1: Working fine code = """ def f1(): print "bar" def f2(): f1() """ exec(code) f2() # Prints "bar" as expected # Case 2: Throws NameError: global name 'f1' is not defined code = """ def f1(): print "bar" def f2(): f1() """ def foo(): exec(code) f2() # NameError foo() Can someone explain me how to avoid that NameError and make exec work inside of a function?
execis to never useexec. There is almost always a better approach.LOAD_GLOBAL, orLOAD_DEREF, orLOAD_FAST, etc.execeffectively creates its own independent parsing context, so the bytecode compiler can't make a fully informed decision about name resolution, unlike if you had defined each function normally. (Posting this as a comment and not an answer because it's too handwavey to actually give you an idea of what specifically is happening and how to fix it)f1()is added to globals, but in case2,f1()is local. Sof1should be added tof2.__closure__in case2. However, in case2 the definition of f2() can not make a correct closures. My quesition and my answer explain why this happen and how to deal with it. Compared with existing answers, my solution avoid makingf1()global in case2.