views:

420

answers:

3

When I call execfile without passing the globals or locals arguments it creates objects in the current namespace, but if I call execfile and specify a dict for globals (and/or locals), it creates objects in the __builtin__ namespace.

Take the following example:

# exec.py
def myfunc():
    print 'myfunc created in %s namespace' % __name__

exec.py is execfile'd from main.py as follows.

# main.py
print 'execfile in global namespace:'
execfile('exec.py')
myfunc()
print    

print 'execfile in custom namespace:'
d = {}
execfile('exec.py', d)
d['myfunc']()

when I run main.py from the commandline I get the following output.

execfile in global namespace:
myfunc created in __main__ namespace

execfile in custom namespace:
myfunc created in __builtin__ namespace

Why is it being run in __builtin__ namespace in the second case?

Furthermore, if I then try to run myfunc from __builtins__, I get an AttributeError. (This is what I would hope happens, but then why is __name__ set to __builtin__?)

>>> __builtins__.myfunc()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'module' object has no attribute 'myfunc'

Can anyone explain this behaviour? Thanks

+2  A: 

First off, __name__ is not a namespace - its a reference to the name of the module it belongs to, ie: somemod.py -> somemod.__name__ == 'somemod' The exception to this being if you run a module as an executable from the commandline, then the __name__ is '__main__'.

in your example there is a lucky coincidence that your module being run as main is also named main.

Execfile executes the contents of the module WITHOUT importing it as a module. As such, the __name__ doesn't get set, because its not a module - its just an executed sequence of code.

Max
Why does it think its __name__ is __builtin__? This hasn't really answered my question.
Moe
The answer provided by David Locke covers this - its covered in the python documentation.
Max
No it doesn't, his answer says that __builtins__ is added to the dictionary passed in for locals (unless I am misinterpreting).
Moe
+1  A: 

The execfile function is similar to the exec statement. If you look at the documentation for exec you'll see the following paragraph that explains the behavior.

As a side effect, an implementation may insert additional keys into the dictionaries given besides those corresponding to variable names set by the executed code. For example, the current implementation may add a reference to the dictionary of the built-in module __builtin__ under the key __builtins__ (!).

Edit: I now see that my answer applies to one possible interpretation of the question title. My answer does not apply to the actual question asked.

David Locke
A: 

As an aside, I prefer using __import__() over execfile:

module = __import__(module_name)
value = module.__dict__[function_name](arguments)

This also works well when adding to the PYTHONPATH, so that modules in other directories can be imported:

sys.path.insert(position, directory)
Daz