views:

196

answers:

2

So I am trying to import a module "foo" that contains directories "bar" and "wiz". "bar" contains python files a.py, b.py, and c.py. "wiz" contains python files x.py, y.py and z.py.

$ ls foo
__init__.py     bar       wiz
$ ls foo/bar
__init__.py     a.py      b.py      c.py
$ ls foo/wiz
__init__.py     x.py      y.py      z.py

In the python shell (more precisely, the django manage.py shell), I type the following and see the following results:

>>> import foo
>>> dir(foo.bar)
['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'a']
>>> dir(foo.wiz)
['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'x', 'y']
>>> foo.wiz.x
<module 'foo.wiz.x' from '/dir/'>
>>> foo.wiz.z
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'module' object has no attribute 'z'

Why are only certain modules being imported here? Why can't I get access to z, or to b or c for that matter? I thought everything would be imported and accessible based solely on the directory that contained them. Also, if the import is failing, it is failing silently.

Does anyone know what is going on here?

+1  A: 

You haven't imported "z" (x was probably imported in some other module):

Python 2.4.3 (#1, Jan 14 2008, 18:31:21)
[GCC 4.1.2 20070626 (Red Hat 4.1.2-14)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
>>> foo.wiz
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'module' object has no attribute 'wiz'
>>> from foo import wiz
>>> foo.wiz
<module 'foo.wiz' from 'foo/wiz/__init__.pyc'>
>>> from foo.wiz import x
>>> foo.wiz.x
<module 'foo.wiz.x' from 'foo/wiz/x.pyc'>
>>> foo.wiz.z
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'module' object has no attribute 'z'
>>> import foo.wiz.z
>>> foo.wiz.z
<module 'foo.wiz.z' from 'foo/wiz/z.py'>
truppo
And, to explain a bit more, the code in foo happens to use or deefine bar and wiz, and the code in wiz happens to use or define x.
andrew cooke
So are you saying that contained modules/sub-modules are NEVER imported implicitly when the parent module (i.e. the directory level module) is imported? Then how is it that foo.bar, foo.wiz, foo.bar.a, foo.wiz.x and foo.wiz.y are imported? ...OK, maybe I figured it out, the django settings.py file is referencing those directories in INSTALLED_APPS, which must be loading the py files. Am I right?Thanks for the help, btw.
lgs
+2  A: 

When importing foo, Python will just load foo/__init__.py, it will not (automatically) load foo.bar or foo.wiz. Therefore, trying to access those without explicitely importing them will raise a AttributeError.

If some module imports sub-modules like foo.bar or foo.bar.a, Python will load the respective files and create a reference to the module object within foo. So it is possible that some modules are available without explicit import.

If you want foo.bar to always export its submodules a, b and c, you can import those from within foo/bar/__init__.py. Then, these modules will be availabe whenever foo.bar is imported.

Ferdinand Beyer