nowox
nowox

Reputation: 29076

How to properly import sub-modules in a Python package?

I am a bit lost about how I should import and organise my sub-modules and I need some literature and some conventions.

The problem

We want to write a new package written in Python that is composed of several components:

We consider this architecture:

pizzafactory
├── __init__.py
├── salt.py 
├── water.py 
├── vegetables
│   ├── __init__.py 
│   └── tomatoes.py 
└── dough
    ├── __init__.py 
    └── flour.py 

Some considerations

The file pizzafactory/__init__.py needs almost all the modules, but because we don't want to pollute the end user namespace with useless things. I would propose to import the ingredients quietly except for those that may be used by the customer:

# pizzafactory/__init__.py
import salt as _salt
import dough as _dough
import vegetables.tomatoes

import oven as _oven # External package

The dough factory will require some water, but the user who need to use that sub-module (to make bread), may don't want to see the water.

# pizzafactory/dough/__init__.py
import pizzafactory.water as _water

Discussion

First, I feel it's always easier to directly import everything either the full package:

import pizzafactory

def grab_tomato():
    return pizzafactory.vegetables.tomatoes.BeefsteakTomato()

or only the required elements:

from pizzafactory.vegetables.tomatoes import BeefsteakTomato

def grab_tomato():
    return BeefsteakTomato()

Both of these methods are common, but it may pollute the pizzafactory namespace, so it may be preferable to mangle the import names. I relalized that nobody does that and I don't know why.

Question

In this generic example, I would like to know how to properly import modules, sub-modules and external packages in order to:

Upvotes: 4

Views: 1258

Answers (1)

sytech
sytech

Reputation: 40861

Both of these methods are common, but it may pollute the pizzafactory namespace, so it may be preferable to mangle the import names. I relalized that nobody does that and I don't know why.

Python is a consenting adult language, we leave the doors unlocked and everything out in the open, for the most part.

If you're concern is just crowding the namespaces, you should define __all__ as well as use single-leading underscores. -- PEP8 suggests that name mangling should only be used to avoid naming clashes, so that's probably why nobody does that.

See the Public and internal interfaces section of PEP8 as well as Naming Convensions.

PEP8 is the guide for the "proper" way to do these kinds of things. Though, it is a guide not necessarily law. You have the flexibility to do what you feel is appropriate for your package, which leads to my favorite section of PEP8 - A Foolish Consistency is the Hobgoblin of Little Minds

Without being sufficiently intimate with the code in a package, one probably could not offer much advice beyond PEP8 on how it should be done. If you have the time, Raymond Hettinger's talk Beyond PEP 8 is a worthwhile watch.

Upvotes: 1

Related Questions