Possibilities for Python Classes Organized Across Files

Possibilities for Python classes organized across files?

A Python file is called a "module" and it's one way to organize your software so that it makes "sense". Another is a directory, called a "package".

A module is a distinct thing that may have one or two dozen closely-related classes. The trick is that a module is something you'll import, and you need that import to be perfectly sensible to people who will read, maintain and extend your software.

The rule is this: a module is the unit of reuse.

You can't easily reuse a single class. You should be able to reuse a module without any difficulties. Everything in your library (and everything you download and add) is either a module or a package of modules.

For example, you're working on something that reads spreadsheets, does some calculations and loads the results into a database. What do you want your main program to look like?

from ssReader import Reader
from theCalcs import ACalc, AnotherCalc
from theDB import Loader

def main( sourceFileName ):
rdr= Reader( sourceFileName )
c1= ACalc( options )
c2= AnotherCalc( options )
ldr= Loader( parameters )
for myObj in rdr.readAll():
c1.thisOp( myObj )
c2.thatOp( myObj )
ldr.laod( myObj )

Think of the import as the way to organize your code in concepts or chunks. Exactly how many classes are in each import doesn't matter. What matters is the overall organization that you're portraying with your import statements.

How to organize my Python code into multiple classes?

Here are the official PEP guidelines for imports: http://www.python.org/dev/peps/pep-0008/#imports

Also please see this StackOverflow question: What are good rules of thumb for Python imports?

You can import a variable from more than one class without a problem but you should try and structure your code so that things aren't circularly imported. Circular import dependency in Python

Are classes in Python in different files?

In Python, one file is called a module. A module can consist of multiple classes or functions.

As Python is not an OO language only, it does not make sense do have a rule that says, one file should only contain one class.

One file (module) should contain classes / functions that belong together, i.e. provide similar functionality or depend on each other.

Of course you should not exaggerate this. Readability really suffers if your module consist of too much classes or functions. Then it is probably time to regroup the functionality into different modules and create packages.


For naming conventions, you might want to read PEP 8 but in short:

Class Names

Almost without exception, class names use the CapWords convention.
Classes for internal use have a leading underscore in addition.

and

Package and Module Names

Modules should have short, all-lowercase names. Underscores can be used
in the module name if it improves readability. Python packages should
also have short, all-lowercase names, although the use of underscores is
discouraged.

Since module names are mapped to file names, and some file systems are
case insensitive and truncate long names, it is important that module
names be chosen to be fairly short -- this won't be a problem on Unix,
but it may be a problem when the code is transported to older Mac or
Windows versions, or DOS.


To instantiate an object, you have to import the class in your file. E.g

>>> from mymodule import MyClass
>>> obj = MyClass()

or

>>> import mymodule
>>> obj = mymodule.MyClass()

or

>>> from mypackage.mymodule import MyClass
>>> obj = MyClass()

You are asking essential basic stuff, so I recommend to read the tutorial.

The Pythonic way of organizing modules and packages

Think in terms of a "logical unit of packaging" -- which may be a single class, but more often will be a set of classes that closely cooperate. Classes (or module-level functions -- don't "do Java in Python" by always using static methods when module-level functions are also available as a choice!-) can be grouped based on this criterion. Basically, if most users of A also need B and vice versa, A and B should probably be in the same module; but if many users will only need one of them and not the other, then they should probably be in distinct modules (perhaps in the same package, i.e., directory with an __init__.py file in it).

The standard Python library, while far from perfect, tends to reflect (mostly) reasonably good practices -- so you can mostly learn from it by example. E.g., the threading module of course defines a Thread class... but it also holds the synchronization-primitive classes such as locks, events, conditions, and semaphores, and an exception-class that can be raised by threading operations (and a few more things). It's at the upper bound of reasonable size (800 lines including whitespace and docstrings), and some crucial thread-related functionality such as Queue has been placed in a separate module, nevertheless it's a good example of what maximum amount of functionality it still makes sense to pack into a single module.

Are multiple classes in a single file recommended?

Here are some possible reasons:

  1. Python is not exclusively class-based - the natural unit of code decomposition in Python is the module. Modules are just as likely to contain functions (which are first-class objects in Python) as classes. In Java, the unit of decomposition is the class. Hence, Python has one module=one file, and Java has one (public) class=one file.
  2. Python is much more expressive than Java, and if you restrict yourself to one class per file (which Python does not prevent you from doing) you will end up with lots of very small files - more to keep track of with very little benefit.

An example of roughly equivalent functionality: Java's log4j => a couple of dozen files, ~8000 SLOC. Python logging => 3 files, ~ 2800 SLOC.

Organizing Python classes in modules and/or packages

A lot of it is personal preference. Using python modules, you do have the option to keep each class in a separate file and still allow for import converters.SomeConverter (or from converters import SomeConverter)

Your file structure could look something like this:

* converters
- __init__.py
- baseconverter.py
- someconverter.py
- otherconverter.py

and then in your __init__.py file:

from baseconverter import BaseConverter
from otherconverter import OtherConverter

Multiple classes in a Python module

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"

How do I structure Python code into modules/packages?

This question asked today, Dynamic Loading of Python Modules, should have your answer.

Python code structure for class organization

In Java the code is structured in packages with you each class in a separate file. Is there any similar practice in python?

Definitely no. Actually, Python doesn't force you to put all your code in classes - plain functions are ok too - so even the "each class" premise doesn't make sense.

Is it better to have each class in a different python file

Definitely no either - it would just make your code a nightmare to maintain.

or should I just dump my code(all my classes) in a single file?

Neither (unless it's a very small app). You want to regroup your code (functions, classes, etc.) in cohesive, decoupled modules/packages, which is the known best practice in all languages anyway. If you have a "full" app with domain code, persistence and UI you'll probably want to use this as your first level packages.



Related Topics



Leave a reply



Submit