Structure of packages

Jean-Paul Calderone exarkun at divmod.com
Wed Jan 9 15:35:23 EST 2008


On Wed, 9 Jan 2008 15:07:16 -0500, Ben Fisher <jamon.ben at gmail.com> wrote:
>I am trying to learn the best way to do intra-package references. My
>package looks like this:
>
>PackageName
>    __init__.py
>    /a
>        __init__.py
>       a.py
>        ...
>    /b
>        __init__.py
>        ...
>    /c
>        __init__.py
>        ...
>    /d
>        __init__.py
>        ...
>I have layered the dependencies so that a depends on b, b depends on
>c, and c depends on d. There are no circular references.
>
>Now I would like to be able to refer to the subpackage b from inside
>the subpackage a. In effect, I would like to say "from '../b' import
>*"
>
>I had thought that "from PackageName.b import *" would work. This
>works for a file in the directory /PackageName, but not for a file in
>the directory /PackageName/a.  It's like when you are running a Python
>file in the directory /PackageName/a it doesn't know about PackageName
>- No module named "PackageName".
>
>Is there a solution to this, or a better way to structure the directories?

You're halfway to the correct answer, actually.  The key is to understand
just how the import process works.

A name is importable if it is a module or package contained by a directory
which is in the sys.path list.  In addition to certain hard-coded paths and
the PYTHONPATH environment variable, the path to the file which defines
__main__ is also added to sys.path.

"from PackageName.b import someName" will work just fine when used from a
file inside PackageName/a/, _as long as PackageName is importable at all_.

If it doesn't work for some reason, the right solution is to make
PackageName importable.  There are other things you can do which will make
the import statement work, but none of them is as good as just making
PackageName importable.  They will rely on some quirk of your environment
or a fragile detail about how your paths are set up or they will require the
user to do something they don't expect to do (the user may be another
programmer in this case).

The simplest way to make PackageName importable is to add the directory it
is a child of to the PYTHONPATH environment variable.  You should do this
in your own environment, not as part of any programs included in PackageName
or any of its modules.  There are other things you can do, such as create
pth files, but they come to the same thing: manipulations of the Python
import path.  You can read more about them in the documentation.

Once you've set up the import path correctly, you'll be able to do the
imports you want to do and they'll work just how you expected them to
work.

This isn't a complete description of Python's import system, but it should
be enough to solve this problem you're having, and provide a good grounding
for further learning.

Hope this helps,

Jean-Paul



More information about the Python-list mailing list