Q on naming nested packages/modules

Stephen Hansen apt.shansen at gmail.com
Wed Sep 2 03:44:10 CEST 2009

> >> An implication of all this is that if now I wanted to create a new
> >> module x.y.z.w, this means that the previously "leaf"-module x.y.z
> >> would become "non-leaf".  In other words, I'd have to:
> >>
> >> 1. create the new directory x/y/z
> >> 2. *rename* the file x/y/z.py to x/y/z/__init__.py
> >> 3. create the file x/y/z/w.py to hold the source for the new x.y.z.w
> >>    module
> >With regard to point 2 -- would it be possible to just move z.py into
> >x/y/z, and put 'from z import *' into x/y/z/__init__.py, for the same
> >effect? Or is that not a good idea?
> I think in this case what you would need is something like 'from
> ..z import *', but this does not work either; one gets the error
> "SyntaxError: 'import *' not allowed with 'from .'".

If you have a "spam.ham" module and you want to refactor it into a package,
there's basically two common things to do as you've discovered.

The first is to turn ham into a package: that entails creating a directory
named ham, and moving ham.py to ham/__init__.py

That works fine and is used by a number of people: I personally hate doing
it, though. I don't like to put significant chunks of code into __init__.py,
but instead just code which largely handles... namespace-issues or
bootstrapping of a package. Partly for the reason you specified: it makes
life a little annoying to have multiple files with completely different
content have the same filename even if they aren't ambiguous due to

I personally MUCH prefer turning ham into a package, and moving the original
"ham.py" to spam/ham/_ham.py. In spam/ham/__init__.py, I'd then do:

from spam.ham._ham import *

>From a usage perspective, everything that used to be in spam.ham will still
be there with all the contents you'd expect (the stuff in
spam/ham/_ham.py)... and people can import spam.ham.eggs if they want or
need to access those details.

(I get around the above traceback you mention by just using an absolute
import -- but I never use relative imports, anyways. They make my soul cry
from a style and management and sanity perspective.)

A third solution would be to change step 2 above to this:
> 2. create the *symlink* x/y/z/__init__.py --> ../z.py

This is IMHO a very, very, very bad idea :)

Yes, it'll work. But involving symlinks will make everything from
distribution to revision control a bit more complicated (even if you're
never intending any Windows users to use it or use a system like svn which
handles symlinks adequately).

It'll just create, in essence, two separate files on your system with the
same content/code. Sure they're not really two separate files, but as far as
Python knows they are.

It just seems like it's asking for trouble :)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20090901/b0f62b2a/attachment.html>

More information about the Python-list mailing list