I want the interface of some module to contain a certain number of functions and classes (and nothing else). I could implement all of those in a single file, and would easily get the interface I want. But since there is a lot of code, I'd prefer to split the whole thing up into several files, say
mypackage/
__init__.py
a.py
b.py
c.py
d.py
To get the desired interface anyway, I define an __init__.py
file for the package that imports all public symbols from a
, b
, c
and d
:
from a import func_a1, func_a2, ClassA1, ClassA2
from b import func_b1, func_b2, ClassB1, ClassB2
from c import func_c1, func_c2, ClassC1, ClassC2
from d import func_d1, func_d2, ClassD1, ClassD2
If I import the package using
import mypackage
the package namespace also contains the symbols a
, b
, c
and d
. These names are implementation details and not part of my interface. I don't want them to appear as "public" symbols. What is the best way of getting rid of them?
The options I considered are
Use a single module instead of a package. The interface will look fine, but the implementation will get less clear than it is now.
Add the line
del a, b, c, d
to the end of __init__.py
. Works ok, but seems like a hack. (For example, you can't import __init__
any more, which works without this line.)
Rename a
, b
, c
and d
to _a
, _b
, _c
and _d
. Now they are included in mypackage
's namespace as "private" symbols, which I'm fine with, but it feels a bit strange that all my filenames start with an underscore (in reality, there are of course more than four submodules).
Any better suggestions? Or thoughts on which option to prefer?
Or am I just to anal and shouldn't care about the whole thing?
PACKAGES. In the __init__.py file of a package __all__ is a list of strings with the names of public modules or other objects. Those features are available to wildcard imports. As with modules, __all__ customizes the * when wildcard-importing from the package.
Packages allow for a hierarchical structuring of the module namespace using dot notation. In the same way that modules help avoid collisions between global variable names, packages help avoid collisions between module names.
The __init__.py files are required to make Python treat directories containing the file as packages. This prevents directories with a common name, such as string , unintentionally hiding valid modules that occur later on the module search path.
Namespace packages allow you to split the sub-packages and modules within a single package across multiple, separate distribution packages (referred to as distributions in this document to avoid ambiguity). For example, if you have the following package structure: mynamespace/ __init__.py subpackage_a/ __init__.py ...
If you really want to remove the names from the namespace then you can just use the del
statement on them and they'll disappear like the wind.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With