Problem with exec

Peter Otten __peter__ at web.de
Fri Dec 16 15:34:09 CET 2005


Antoon Pardon wrote:

> I have the following little piece of code:
> 
> class Cfg:pass
> #config = Cfg()
> 
> def assign():
>   setattr(config, 'Start' , [13, 26, 29, 34])
> 
> def foo():
>   config = Cfg()
>   dct = {'config':config, 'assign':assign}
>   exec "assign()" in dct
>   print config.Start
> 
> foo()
> 
> 
> When I execute this I get the following error:
> 
> Traceback (most recent call last):
>   File "mod1.py", line 13, in ?
>     foo()
>   File "mod1.py", line 10, in foo
>     exec "assign()" in dct
>   File "<string>", line 1, in ?
>   File "mod1.py", line 5, in assign
>     setattr(config, 'Start' , [13, 26, 29, 34])
> NameError: global name 'config' is not defined
> 
> Now I don't understand this. In the documentation I read the following:
> 
>   If only the first expression after in is specified, it should be a
>   dictionary, which will be used for both the global and the local
>   variables.
> 
> I provided a dictionary to be used for the global variables and it
> contains a 'config' entry, so why doesn't this work?


If you have a module

v
def f(): return v


and call f in another module

print f()

where no global variable v is defined, would you expect that call to fail?
Of course not, but how can f look up the variable v then? The function
object keeps a reference of the global namespace it was defined in.
For your example that means the assign() function will look up the config
object in the module's globals(), not in the dictionary you provide to exec

One way to fix your problem would be to define the assign() function inside
the exec'd string.

Peter




More information about the Python-list mailing list