3

I'm currently working on a project that I am structuring in the following manner:

.
├── example_app
│   ├── __init__.py
│   ├── app.py
│   ├── requirements.txt
│   └── classes
│       ├── ExampleClass1.py
│       ├── ExampleClass2.py
│       ├── __init__.py
└── tests
    └── test_app.py

Inside of classes/__init__.py I have defined a base class for all of the other "ExampleClasses" to inherit from. Then, inside of app.py I need to import all of these classes. However, this becomes very verbose, as I have to type:

from example_app.classes.ExampleClass1 import ExampleClass1
from example_app.classes.ExampleClass2 import ExampleClass2
...

Is there a way to structure this in a better way? Ideally I would like to keep each class in a separate file as they are not really similar to each other. I thought of importing all the classes inside of classes/__init.py but that does not seem right.

Note that although I only pictured 2 example classes there could be several (tens) of them so importing by hand is quite cumbersome and brittle.

1
  • Your modules (ExampleClass*.py) has the classes of the same names? Commented Feb 11, 2021 at 11:16

3 Answers 3

1

In my opinion, importing all the classes you want to expose from the subpackage classes inside its __init__.py is the way to go. In fact, that's what many top-tier Python libraries/frameworks do (see TensorFlow/Keras layers subpackage here and Python's multiprocessing subpackage here).

When doing that, however, you should probably follow Google Python Style Guide and:

Use import statements for packages and modules only, not for individual classes or functions. Note that there is an explicit exemption for imports from the typing module.

In your case, it would translate to this:

example_app/classes/__init__.py:

from example_app.classes.ExampleClass1 import ExampleClass1
from example_app.classes.ExampleClass2 import ExampleClass2

example_app/__init__.py:

# ...
from example_app import classes
# ...

Some other .py:

from example_app import classes
ex1_instance = classes.ExampleClass1()

Or even better:

import example_app as ex
ex1_instance = ex.classes.ExampleClass1()
Sign up to request clarification or add additional context in comments.

Comments

0

You can treat a module as a class. If your module ExampleClassN.py is only to define a class ExampleClassN, just add the following two line at the end of each module.

import sys
sys.modules[__name__] = ExampleClassN  # N = 1, 2, ...

Then you can

from example_app.classes import ExampleClass1
from example_app.classes import ExampleClass2
...

or

from example_app.classes import (
    ExampleClass1,
    ExampleClass2,
    ...
)

or

from example_app.classes import *

Comments

0

First off, the __init__.py shouldn't contain your base class. It is better to have separate file for the base class, as __init__.py usually serves as initializaion of the module.

What you can do is following:

  • use __init__.py to import all of the classes from the submodules. Eg.

      import ExampleClass1.ExampleClass1
      import ExampleClass2.ExampleClass2
    
      __all__ = ['ExampleClass1','ExampleClass2']
    

Finally in order to use the wildcard operator, e.g. from classes import * you need to add the following line

__all__ = ['ExampleClass1','ExampleClass2']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.