简体   繁体   中英

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:

  • Classes and functions useful for the end user
  • Classes and functions rarely used
  • Utilities classes and functions only needed by the package itself
  • External modules

We consider this architecture:

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

Some considerations

  • The end user don't need to use raw ingredients such as dough or water
  • The customer only need pizzas described in pizzafactory/__init__.py
  • The dough factory requires salt and water
  • The customer may want to add some tomatoes on its pizza.

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:

  • Minimize the namespace footprint
  • Help the end user to clearly see only what he is intended to used

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM