3

Tried searching the site, but cannot find an answer to my problem:

Lets say I have a module, named mymodule.py that contains:

def a():
    return 3

def b():
    return 4 + a()

Then the following works:

import mymodule
print(mymodule.b())

However, when I try defining the module contents dynamically:

import imp

my_code = '''
def a():
    return 3

def b():
    return 4 + a()
'''

mymodule = imp.new_module('mymodule')
exec(my_code, globals(), mymodule.__dict__)
print(mymodule.b())

Then it fails in function b():

Traceback (most recent call last):
File "", line 13, in <module>
File "", line 6, in b
NameError: global name 'a' is not defined

I need a way to preserve the hierarchical namespace searching in modules, which seems to fail unless the module resides on disk.

Any clues as to whats the difference?

Thanks, Rob.

2 Answers 2

3

You're close. You need tell exec to work in a different namespace like so (see note at bottom for python 3.x):

exec my_code in mymodule.__dict__

Full example:

import imp

my_code = '''
def a():
    return 3

def b():
    return 4 + a()
'''

mymodule = imp.new_module('mymodule')

exec my_code in mymodule.__dict__
print(mymodule.b())

This said, I've not used this before, so I'm not sure if there are any weird side-effects to this, but it looks like it works to me.

Also, there's a small blurb about 'exec in ...' in the python docs here: http://docs.python.org/reference/simple_stmts.html#the-exec-statement

Update

The reason your original attempt didn't work correctly is you were passing your current module's globals() dictionary, which is different than the globals() your new module should use.

This exec line also works (but isn't as pretty as the 'exec in ...' style):

exec(my_code, mymodule.__dict__, mymodule.__dict__)

Update 2: Since exec is now a function in python 3.x, it has no 'exec in ...' style, so the line above must be used.

Sign up to request clarification or add additional context in comments.

4 Comments

is there a python 3.x version of "exec ... in " ? Can't seem to find it in the exec() function. Thanks
it doesn't look like it... see my update, the 'less pretty' version should work for you in 3.x (I've not tried it yet, so let me know if it works)
Alright, I've tested exec(my_code, mymodule.__dict__, mymodule.__dict__) in python3 and it seems to work fine. I've updated my answer to reflect this as well.
Okay Ill give that a shot it seems very promising (I have to modify some things for my original project). Thanks very much.
0

That is not how exec() is designed to be used. exec() doesn't actually put the code it runs "into" any module - it runs it in the module-space that exec() was called from.

1 Comment

so are there any alternatives to exec() that reproduce the module behaviour I need? thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.