views:

379

answers:

3

I want to define classes in Python, but I'm currently putting them in modules, contained within packages.

Is there a cleaner way of doing this? Is it okay to define classes in __init__.py of the package itself?

I'm still learning how to arrange my Python source code, but this seems to be creating a slight ambiguity?

Thanks to all!

+4  A: 

It's fine to have class statements in __init__.py, just as much as def statements or other assignments, but I'd suggest avoiding it -- it makes writing good, solid unit tests a bit harder (the unit tests then have to be written to import the package as such, rather than a specific module inside it). I suggest having __init__.py either empty (best, most often), or composed strictly of import and from statements, to make unit tests trivially easy.

I'm not sure what "ambiguity" you have in mind, though -- what's "ambiguous"...?

Alex Martelli
The ambiguity is that I want to avoid having to create module names under my package just for the sake of having a name to contain the class. Especially when the package name is sufficient enough.I'm not trying to re-tool python convention, simply get familiar with the best practices ;)Thanks!
Omega
@Omega, as Lennart says in his comment on your question, looks like you're thinking of redundancy, not ambiguity. @voyager, I have no idea what you're talking about.
Alex Martelli
@Alex: It happens quite too often, sadly :'( http://meta.stackoverflow.com/questions/21855/monty-python-book-ad-showing-up-in-python-questions
voyager
Oh, _that_ (Monty;-) Python, I see...
Alex Martelli
+3  A: 

Place each class (or each set of closely related classes) in their own files in your module.

For instance, the definition for class Box can go in box.py. Or if you have two shapes, Box and Circle, put them in shapes.py. Try to use common sense to decide how to organize things.

Don't put things in __init__.py unless you find an obvious necessity to do this.

Fragsworth
That creates the "ambiguity" I refer to, as to import it you get import package.box.Box...Yikes!
Omega
You mean *redundancy*. Yes, it's redundant. Do it anyway.If you want to get rid of the redundancy do a `from package.box import Box` in the `__init__.py`
Lennart Regebro
A: 

How you structure you package depends on how it is to be used. There are several cases:

(1) You package contains many different loosely related classes which can be used separately. In this case you should create submodules (or even subpackages) so that user uses import package.thing or import package.another.

(2) Your package must always work together as a single program. In that case, it makes sense to write a "public interface" so that user can do

import package

package.Thing().work() ...
package.do_something()

After you finalize public interface, how you structure your package should be an implementation detail and you are free to create several files without changing the public interface, e.g.

# _thing.py
"Implementation of Thing. Don't import this file --- use main package instead."
class Thing: ... 

# __init__.py
from ._thing import Thing

It's still best not to declare anything in the __init__.py since it's harder to unittest. However, you might not know in the beginning how you want your files to be organized. In that case I would first write a dummy __init__.py with all the empty classes and then move them one by one into other files as I fill them in.

(3) It's not hard to see that the most practical is a middle way where you structure your package into separate files but also import the most useful classes and functions in the __init__.py. User will have the choice of importing the main namespace or directly a submodule --- yes, that's redundant, but "practicality beats purity".

ilya n.