Restructure Your Modules in Python

serhatteker

Serhat Teker

Posted on December 20, 2021

Restructure Your Modules in Python

Intro

If your module becomes too big as you expand your codebase with new features you can restructure it to a package. Let's assume you have a field.py module with below classes;

# db/models/fields.py
...



class OrderWrt(fields.IntegerField):
    ...



class JSONField(CheckFieldDefaultMixin, Field):
    ...



class RelatedField(FieldCacheMixin, Field):
    ...


...
Enter fullscreen mode Exit fullscreen mode

And your directory structure looks like this;

.
└── db
    └── models
        └── fields.py

Enter fullscreen mode Exit fullscreen mode

Solution

You can move your classes to related modules in a fields package;

# db/models/fields/proxy.py
...


class OrderWrt(fields.IntegerField):
    ...
Enter fullscreen mode Exit fullscreen mode
# db/models/fields/json.py
...



class JSONField(CheckFieldDefaultMixin, Field):
    ...

Enter fullscreen mode Exit fullscreen mode
# db/models/fields/related.py
...



class RelatedField(FieldCacheMixin, Field):
    ...
Enter fullscreen mode Exit fullscreen mode

Your package structure now looks like below;

.
└── db
    └── models
        └── fields
            ├── json.py
            ├── proxy.py
            └── related.py

3 directories, 3 files
Enter fullscreen mode Exit fullscreen mode

However this will broke your codebase since all of your imports' paths are false now. In order to fix this import your classes into __init__.py module of your fields package:

# db/models/fields/__init__.py
from db.models.fields.proxy import OrderWrt
from db.models.fields.json import JSONField
from db.models.fields.related import RelatedField
Enter fullscreen mode Exit fullscreen mode

The structure looks like this;

.
└── db
    └── models
        └── fields
            ├── __init__.py
            ├── json.py
            ├── proxy.py
            └── related.py

3 directories, 4 files
Enter fullscreen mode Exit fullscreen mode

Now imports are okay, but if you use flake8 code style and quality tool —you should, now this __init__ module will throw F401 unused errors;

  • (F401) 'db.models.fields.json.JSONField' imported but unused
  • (F401) 'db.models.fields.proxy.OrderWrt' imported but unused
  • (F401) 'db.models.fields.related.RelatedField' imported but unused

We can prevent that by using __all__:

# db/models/fields/___init___.py
from db.models.fields.json import JSONField
from db.models.fields.proxy import OrderWrt
from db.models.fields.related import RelatedField


__all__ = ["JSONField", "OrderWrt", "RelatedField"]
Enter fullscreen mode Exit fullscreen mode

So by this last modification you restructured your big module in a package.

All done!

💖 💪 🙅 🚩
serhatteker
Serhat Teker

Posted on December 20, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related