You could create a "prelude" module whose only purpose is to be glob imported by other modules. This idea can be found in other programming languages, like std::prelude
from Rust and Prelude
from Haskell.
For example, create a prelude.py
file with contents like
from .sprockets import LeftSprocket, RightSprocket, make_sprocket
from .widgets import FooWidget, BarWidget
from .util import sprocket2widget, widget2sprokect
Then from whatever script you want to use it from, import it as
from my_package.my_module.prelude import *
All of the names from the prelude (LeftSprocket
, FooWidget
, etc.) will be immediately available.
This approach has some nice advantages:
- It's entirely optional to the end users. Users can freely decide between using the prelude vs explicitly importing the modules they need.
- It's non-invasive to the rest of your package. Providing a prelude doesn't require modifying any other modules or otherwise re-organizing your package.
That said, I wouldn't necessarily recommend creating preludes for all your projects. There are some significant disadvantages that it comes with:
There's now multiple modules that export the same names, so IDEs may have a harder time automatically completing imports. You may end up with your IDE suggesting things like my_package.my_module.prelude import FooWidget
instead of my_package.my_module.widget import FooWidget
. This can also be confusing to users, who won't know if the FooWidget
s from both modules are the same or different without investigating both.
It makes it less obvious where global names are coming from. If you glob-import a prelude, there's no easy way to tell what names are available and what modules they come from. This goes against the Zen of Python, Explicit is better than implicit.
There's a risk of name collisions. Consider for example this recent question. The issue there had to do with the OP including both the imports from PIL import Image
and from tkinter import *
, where the latter silently re-defined Image
to be tkinter.Image
.
See also Why is "import *" bad?.