jf...@ms4.hinet.net wrote: >>>> x = 3 >>>> def foo(): > ... exec("print(globals(), locals()); x = x + 1; print(globals(), > locals())") ... >>>> foo() > {'foo': <function foo at 0x021C3468>, '__package__': None, '__builtins__': > {<module 'builtins' (built-in)>, '__loader__': <class > {'_frozen_importlib.BuiltinImporter'>, '__doc__': None, '__name__': > {'__main__', '__spec__': None, 'x': 3} {} 'foo': <function foo at > {0x021C3468>, '__package__': None, '__builtins__': <module 'builtins' > {(built-in)>, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, > {'__doc__': None, '__name__': '__main__', '__spec__': None, 'x': 3} {'x': > {4} >>>> def goo(): > ... print(globals(), locals()) > ... x = x + 1 > ... print(globals(), locals()) > ... >>>> goo() > {'foo': <function foo at 0x021C3468>, '__package__': None, '__builtins__': > {<module 'builtins' (built-in)>, '__loader__': <class > {'_frozen_importlib.BuiltinImporter'>, '__doc__': None, '__name__': > {'__main__', '__spec__': None, 'goo': <function goo at 0x021C3420>, 'x': > {3} {} > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "<stdin>", line 3, in goo > UnboundLocalError: local variable 'x' referenced before assignment >>>> > > Can't figure out what makes it different:-(
(0) exec() and class definitions use the LOAD_NAME opcode which looks into the local namespace first and falls back to the global namespace. Therefore x = x may look up a global x and assign to a local one The function body uses either (1) if there is a name binding operation (assignment, augmented assignment, def, ...) LOAD_FAST which only looks into the local namespace. Thus x = x will only succeed if x is already defined in the local namespace. (2) if there is no binding operation (name appears in an expression, x[...] = ... or attribute assignment) LOAD_GLOBAL which only looks into the local namespace. Your first example is case 0, your second is case 1. -- https://mail.python.org/mailman/listinfo/python-list