[Tutor] help understanding __import__() oddness
shaleh at speakeasy.net
shaleh at speakeasy.net
Wed Jul 26 00:07:39 CEST 2006
I have a script trying to use __import__ to read Python modules as config files (among other things). Sounds simple enough.
To put it simply, full paths seem to fail but relative path work IF the script is in that path too.
When I run it I get:
$ cd /tmp
$ ls
importer.py my
$ ls my
settings.py settings.pyc
$ ./importer.py
Starting in /tmp
Found /tmp/my/settings
No module named /tmp/my/settings
Found my/settings
my/settings /tmp/my/settings.pyc
[code]
import os
import os.path
print "Starting in " + os.getcwd()
app_path = '/tmp/my/settings'
app_path2 = 'my/settings'
if os.path.exists(app_path + '.py'):
print "Found", app_path
try:
f = __import__(app_path, globals(), locals(), [])
print f.__name__, f.__file__
except Exception, e:
print e
# uncomment me if started somewhere else
# print "Moving to /tmp"
# os.chdir("/tmp")
if os.path.exists(app_path2 + '.py'):
print "Found", app_path2
try:
f = __import__(app_path2, globals(), locals(), [])
print f.__name__, f.__file__
except Exception, e:
print e
[/code]
If I move the script to /foo and add a os.chdir() call before the second module attempt BOTH fail:
$ ./importer.py
Starting in /home/sperry
Found /tmp/my/settings
No module named /tmp/my/settings
Moving to /tmp
Found my/settings
No module named my/settings
Obviously I am confused. None of the docs I have read indicate this should be the case. What gives?
I was just about to hit send when a thought occured to me. What about sys.path? The script's starting directory is added to the path. Which makes the relative lookups work. Fair enough. But if I start the interpreter in ~/ and do:
>>> __import__("/tmp/my/settings")
<module '/tmp/my/settings' from '/tmp/my/settings.pyc'>
It works. <shrug>
Simple script:
$ ./test.py
1. Failed
/tmp/my/settings
[code]
import sys
try:
f = __import__("/tmp/my/settings")
print f.__name__
except:
print "1. Failed"
sys.path.insert(0, '')
try:
f = __import__("/tmp/my/settings")
print f.__name__
except:
print "2. Failed"
[/code]
That works. What gives?
More information about the Tutor
mailing list