Reputation: 717
Let's say you have a string containing a path to a Python script and you want to load and execute that script in transparent way (so that there are not fundamental differences for inner script compared to being run directly via “python path”). And then get the resulting global dict. I thought that runpy.run_path() does this but there are two issues. If the path contains some unicode character then it doesn't work (see http://bugs.python.org/issue17588). And most importantly, given global dict is just a copy of original one, since this original one is purged when temporary module object is garbage collected. So a function object have corrupted __globals__ dict (see http://bugs.python.org/issue18331).
Have you any ideas how to run the inner script?
Update: See my current approach – http://bpaste.net/show/RzAbQxLNXiJsXYm2fplz/ . Any suggestions? Improvements? For example about the details of what can be different from point of view of a script being run. I know about issue with realoading __main__.
Upvotes: 6
Views: 2213
Reputation: 8181
Importing a module executes the code at the top level, and that module's "global" namespace gets imported as the name of the module
james@bodacious:~$cat test.py
def func():
pass
myname = "michael caine"
print "hello, %s" % myname
james@bodacious:~$python
Python 2.7.5 (default, Jul 12 2013, 18:42:21)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
hello, michael caine
>>> dir(test)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'func', 'myname']
>>>
if the code you want to be run is at the top level of the file, just importing the module will execute the code and give you access to its "global" namespace all in one convenient package. If the code you want to run isn't at the top level (eg, if it's in a main()
function that only gets triggered with the common if __name__=="__main__"
trick), you can call that function yourself:
james@bodacious:~$cat test.py
def main():
print "hello there!"
if __name__=="__main__":
main()
james@bodacious:~$python
Python 2.7.5 (default, Jul 12 2013, 18:42:21)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> test.main()
hello there!
>>>
Of course, it's possible that you file you want to import is not in sys.path, so can't be simply loaded with import
. A simplistic solution might be to manipulate sys.path
, but How to import a module given the full path? describes better solutions using imp.load_source()
Upvotes: 1