Organizing Python classes in modules and/or packages

34,342

Solution 1

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

Solution 2

Zach's solution breaks on Python 3. Here is a fixed solution.

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 converters.baseconverter import BaseConverter
from converters.otherconverter import OtherConverter

Solution 3

The above solutions are good, but the problem with importing modules in __init__.py is that this will cause all the modules to be loaded twice(inefficient). Try adding a print statement at the end of otherconverter.py and run otherconverter.py. (You'll see that the print statement is executed twice)

I prefer the following. Use another package with name "_converter" and define everything there. And then your "converters.py" becomes the interface for accessing all public members

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

*  converters.py

where converters.py is

from _converters.someconverter import SomeConverter
from _converters.otherconverter import OtherConverter
...
...
...
converters = [SomeConverter, OtherConverter, ...]

And as the previous solutions mentioned, it is a personal choice. A few practices involve defining a module "interace.py" within the package and importing all public members here. If you have many modules to load, you should choose efficiency over aesthetics.

Share:
34,342
deamon
Author by

deamon

Updated on October 10, 2020

Comments

  • deamon
    deamon over 3 years

    I like the Java convention of having one public class per file, even if there are sometimes good reasons to put more than one public class into a single file. In my case I have alternative implementations of the same interface. But if I would place them into separate files, I'd have redundant names in the import statements (or misleading module names):

    import someConverter.SomeConverter
    

    whereas someConverter would be the file (and module) name and SomeConverter the class name. This looks pretty inelegant to me. To put all alternative classes into one file would lead to a more meaningful import statement:

    import converters.SomeConverter
    

    But I fear that the files become pretty large, if I put all related classes into a single module file. What is the Python best practise here? Is one class per file unusual?