My package has the following structure:
mobilescouter/ __init__.py #1 mapper/ __init__.py #2 lxml/ __init__.py #3 vehiclemapper.py vehiclefeaturemapper.py vehiclefeaturesetmapper.py ... basemapper.py vehicle/ __init__.py #4 vehicle.py vehiclefeature.py vehiclefeaturemapper.py ...
I’m not sure how the
__init__.py files should be correctly written.
__init__.py #1 looks like:
__all__ = ['mapper', 'vehicle'] import mapper import vehicle
But how should for example
__init__.py #2 look like? Mine is:
__all__ = ['basemapper', 'lxml'] from basemaper import * import lxml
When should be
__all__ is very good – it helps guide import statements without automatically importing modules
import * is redundant, only
__all__ is needed
I think one of the most powerful reasons to use
import * in an
__init__.py to import packages is to be able to refactor a script that has grown into multiple scripts without breaking an existing application. But if you’re designing a package from the start. I think it’s best to leave
__init__.py files empty.
foo.py - contains classes related to foo such as fooFactory, tallFoo, shortFoo
then the app grows and now it’s a whole folder
foo/ __init__.py foofactories.py tallFoos.py shortfoos.py mediumfoos.py santaslittlehelperfoo.py superawsomefoo.py anotherfoo.py
then the init script can say
__all__ = ['foofactories', 'tallFoos', 'shortfoos', 'medumfoos', 'santaslittlehelperfoo', 'superawsomefoo', 'anotherfoo'] # deprecated to keep older scripts who import this from breaking from foo.foofactories import fooFactory from foo.tallfoos import tallFoo from foo.shortfoos import shortFoo
so that a script written to do the following does not break during the change:
from foo import fooFactory, tallFoo, shortFoo
__init__.py files are empty more often than not. In particular, I never have a
from blah import * as part of
__init__.py — if “importing the package” means getting all sort of classes, functions etc defined directly as part of the package, then I would lexically copy the contents of
blah.py into the package’s
__init__.py instead and remove
blah.py (the multiplication of source files does no good here).
If you do insist on supporting the
import * idioms (eek), then using
__all__ (with as miniscule a list of names as you can bring yourself to have in it) may help for damage control. In general, namespaces and explicit imports are good things, and I strong suggest reconsidering any approach based on systematically bypassing either or both concepts!-)