Reputation: 143
So, this is a set of questions about how to use __init__.py in packages/sub-packages. I have searched, and surprisingly not found a decent answer to this.
If I have the following structure (which is just a simplified example obviously):
my_package/
__init__.py
module1.py
my_sub_package/
__init__.py
module2.py
the contents of module1.py is
my_string = 'Hello'
the contents of module2.py is
my_int = 42
What should be in the __init__.py files?
I can leave them empty, in which case, import my_package
does nothing really (obviously it imports the package, but the package effectively contains nothing). This is fine obviously, and what should happen in most cases.
What I'd like in this case though is for import my_package
to allow me to use my_package.module1.my_string
and my_package.my_sub_package.module2.my_int
.
I can add __all__ = [ 'module1' ]
to my_package/__init__.py and __all__ = [ 'module2' ]
to my_package/my_sub_package/__init__.py, but this only affects imports using a wildcard as I understand it (so only from my_package import *
and from my_package.my_sub_package import *
).
I can achieve this by putting
import my_package.module1
import my_package.my_sub_package
in my_package/__init__.py and
import my_package.my_sub_package.module2
in my_package/my_sub_package/__init__.py, but is this a bad idea? It creates a (seemingly) infinite series of my_package.my_package.my_package.... when I do this in the Python interpreter (3.5.5).
If I wanted instead to be able to do the following
import my_package
print(my_package.my_string)
print(str(my_package.my_sub_package.my_int))
i.e. I wanted to use module1 and module2 purely for separating code into smaller more readable files if I actually had lots of modules in each package (which obviously doesn't apply in this trivial example, but can easily)
is doing from my_package.module1 import *
in my_package/__init__.py and from my_package.my_sub_package.module2 import *
in my_package/my_sub_package/__init__.py a reasonable way to do that? I don't like the use of the wildcard import, but it seems like it would be impractically verbose to import everything defined in a (real) module, listing them all.
Is there a way I can achieve the above without having to put the names of the packages into the source code in them? I ask because I'd like to avoid having to change it in multiple places if I renamed the package (again, simple in this trivial example, can be done by an IDE or script in reality, but would be nice to know how to avoid).
Upvotes: 3
Views: 3006
Reputation: 12261
In my_package/__init__.py
, use
from . import my_sub_package
etc.
See for example NumPy's __init__.py
, which has from . import random
, and allows
import numpy as np
np.random.random
Wildcard imports inside a single package tend to be common, provided you have __all__
defined in the modules and subpackages you import from.
Again an example from NumPy's __init__.py
, which has several wildcard imports.
Here's part of that __init__.py
:
from . import core
from .core import *
from . import compat
from . import lib
from .lib import *
from . import linalg
from . import fft
from . import polynomial
from . import random
from . import ctypeslib
from . import ma
from . import matrixlib as _mat
from .matrixlib import *
from .compat import long
Notice also the two core
import lines. Both numpy.core
and the core definitions (functions, classes etc) are then available.
When in doubt how to do something, or whether something is good practice, have a look at a few well-known libraries or packages. That can help gaining some valuable insights.
Upvotes: 9