funcs vs vars in global namespace
Bengt Richter
bokr at oz.net
Tue Sep 14 16:57:53 EDT 2004
On Tue, 14 Sep 2004 14:25:04 -0400, David Rysdam <drysdam at ll.mit.edu> wrote:
>Alex Martelli wrote:
>> David Rysdam <drysdam at ll.mit.edu> wrote:
>> ...
>>
>>>OK, dumb question #1:
>>>
>>>Why do this:
>>>
>>>sub_module = __import__(which_module_this_time)
>>>vars(sub_module).update(which_dict_this_time)
>>>
>>>When I could just do this:
>>>
>>>__import__(which_module_this_time, which_dict_this_time)
>>>
>>>?
>>
>>
>> You can do whatever you wish, but what makes you think these constructs
>> have similar effects? Quoting from Python's online docs on __import__,
>>
>> """
>> the standard implementation does not use its locals argument at all,
>> and uses its globals only to determine the package context of the
>> import statement
>> """
>>
>> In short, the standard implementation of __import__ does NOT alter in
>> any way the dict of the module it imports.
>>
>>
>> Alex
>
>Ah, I see.
>
>Your "which_dict_this_time" dictionary, how are you imagining that
>working? I was just mapping function name strings to functions
>({'logError':logError}), but (long story short) that isn't working how I
>want. But shouldn't I be able to define the function right there in the
>dictionary itself?
>
>Perhaps this is getting too non-obvious, magical and unmaintainable, though.
Maybe this will give you some ideas:
Here empty.py is just a single blank text line with a (windows in this case, which
for the heck of it I'll show in binary) EOL:
>>> open('empty.py','rb').read()
'\r\n'
>>> import empty
When you import, you automatically get some stuff in the module directory
>>> dir(empty)
['__builtins__', '__doc__', '__file__', '__name__']
>>> vars(empty).keys()
['__builtins__', '__name__', '__file__', '__doc__']
If you have source defining a function, you can exec the definition in a directory,
which will become what the function sees as its global directory. So,
>>> exec """
... def foo(a):
... return a+b
... """ in empty.__dict__
It shows up:
>>> dir(empty)
['__builtins__', '__doc__', '__file__', '__name__', 'foo']
since b is retrieved from the global dict, we better put something there.
That happens to be the dict that stores module attributes, so we can:
>>> empty.b = 100
>>> empty.foo(23)
123
>>> empty.b = 200
>>> empty.foo(23)
223
... as expected.
We can verify that foo's global dict is empty's dict:
>>> empty.foo.func_globals is empty.__dict__
True
If you have definitions of functions in source files, you can execfile them
in a similar manner:
First I'll creat a source right here, though I could have done it in an editor
>>> open('baz.py','w').write("""
... def baz(x):
... return 2*b+x
... """)
Verify
>>> print '----\n%s----'%open('baz.py').read()
----
def baz(x):
return 2*b+x
----
Use execfile do define it in empty:
>>> execfile('baz.py', empty.__dict__)
It shows up:
>>> dir(empty)
['__builtins__', '__doc__', '__file__', '__name__', 'b', 'baz', 'foo']
Check b:
>>> empty.b
200
>>> empty.baz(44)
444
HTH. Note that exec-ing or execfile-ing untrusted source is not safe.
BTW, if in the same interpreter execution session you import empty from another module,
the updated contents should be visible. E.g.,
>>> open('mimpbaz.py','w').write("""import empty
... """)
>>> print '----\n%s----'%open('mimpbaz.py').read()
----
import empty
----
>>> import mimpbaz
>>> dir(mimpbaz)
['__builtins__', '__doc__', '__file__', '__name__', 'empty']
>>> mimpbaz.empty is empty
True
>>> mimpbaz.empty.b
200
>>> mimpbaz.empty.baz(3056)
3456
recalling that baz did
>>> 2*200+3056
3456
Note that the source of empty.py has not changed
>>> print '----\n%s----'%open('empty.py').read()
----
----
>>> open('empty.py').read()
'\n'
Of course, it doesn't have to start out empty. The point is
exec and execfile don't save a compiled .pyc for you to make
it faster next time, whereas import does (unless it's prevented
by lack of write privilege or such, I think).
Regards,
Bengt Richter
More information about the Python-list
mailing list