Multiple classes in a Python module
Solution 1
Here is a useful rule of thumb from what I have seen of typical Java projects:
The bottom-most package in Java should be a file in Python
What does that mean? If your Java project was organized:
toplevel/
subproject/
Foo.java
Bar.java
subproject2/
Baz.java
Qux.java
Then your Python project should look like:
toplevel/
subproject.py <-- put class Foo, Bar here
subproject2.py <-- put class Baz, Qux here
Things to notice re: organization:
- Do not use inner classes. Just put classes in the same module
- By convention, things that start with _ are "private"
- It's OK to have "public variables"
Solution 2
Think it this way.
In java what you write is a Class where in the case of Python, you write a module instead of a class. So a module can contain several classes. Whenever you want to use a particular class, import the respective module first and then call the class to make objects.
Here's an example.
Classes.py (This is a module named 'Classes')
class MyClass(object):
def greet(self):
print("Hello World")
class MyNextClass(object):
def greetAgain(self):
print("Hello again")
Now I can import this module from anywhere I wish
import Classes
if __name__ == '__main__':
a=Classes.MyClass()
a.greet()
b=Classes.MyNextClass()
b.greetAgain()
Solution 3
When in doubt, just look at Python's standard libraries :)
For example, the standard calendar module contains 31 classes. So yes, it is ok.
Solution 4
It is absolutely proper to do so. A module groups related functionality. If that functionality is implemented in several classes (e.g., Tree, Node, Leaf) then it is appropriate to place them together.
A module is more closely associated with a Java package than a Java class. You can also implement a module as a folder, named for the module, with an __init__.py
file inside (so Python can identify the module as such; the __init__.py
may also optionally include initialization code and lists of classes, functions, and sub-packages to export.)
Solution 5
It is certainly a normal thing to do in Python. When and why you choose one over the other is partly a matter of taste, and partly convention.
If you're still getting to know Python, and therefore its conventions, reading the style guide is well worth your time.

ralph
Updated on July 16, 2022Comments
-
ralph 5 months
I'm very new to Python (I'm coming from a JAVA background) and I'm wondering if anyone could help me with some of the Python standards. Is it a normal or "proper" practice to put multiple class in a module? I have been working with Django and started with the tutorials and they place their database model classes in the same module. Is this something that is normally done or should I stick with 1 class per module? Is there a reason I would do one over the other?
Hope I'm being clear and not to generic. Thanks to everyone in advance!
-
Mike Graham over 12 yearsNote, most style standards have
__init__.py
being empty or close to empty. It turns out it can be confusing and feel disorganized to have modules that contain both submodules and normal stuff at the same levels. -
blokeley over 12 years@Mike Graham: django places lots of functions and classes in
__init__.py
files and django seems to be well-regarded. -
Mike Graham over 12 years@blokeley, Django is certainly popular, but I don't know if it is widely regarded as adhering to Python best principles. I have never used Django myself, but it sounds like it requires people to do a log of ugly, awful things to get their apps working. See jcalderone.livejournal.com/39794.html and effbot.org/pyfaq/what-is-init-py-used-for.htm and various SO threads to read about
__init__.py
usually being emptyish. Projects in my site-packages that do this include Twisted, PyMeta, and PyFlakes. -
Joel M almost 3 yearsComing from outside of python its really hard for me to put multiple classes in the same file, or to have filenames not be the same as classes.
-
Joel M almost 3 yearsThis also seems to work, from subproject.Foo import *. Is there a reason why we wouldn't just do it this way, and then have one class per file, and many classes in a module? It's a bit annoying to write and you can't import all classes in one go. Is there a way to import all classes in a module using __init__.py and __all__ (without having to use the class as Foo.Foo())?