pythonimportnamespacesrelative-import

Python: relatively import the containing package


I have the following package structure (drastically simplified from a real use case):

mypackage/
├── __init__.py
├── mod1.py
│   ├── def func1(): return 1
│   └── ...
│
├── mod2.py
│   ├── def func2(): return 2
│   └── ...
└── mod3.py

with __init__.py like this

from .mod1 import *
from .mod2 import *

Now, in mod3.py I want to access the packages complete namespace with one alias like res = p.func1() + p.func2() and I want this to achieve this by one relative import statement. Is this possible?

I don't want an absolute import like import mypackage as p (because the code should be indifferent on renaming the package).

Note, this is related to but different from this unanswered question from 2009.


Solution

  • Generally you do not want to use asterisks while doing imports so you can use this while still using relative import:

    from . import mod1
    

    You can call the function like this:

    mod1.func1()
    

    PS: If you are using Python 3 you are no longer required to use __init__.py to define packages.

    Edit: If you want use common namespace for all those functions you have imported you could create a new module to use as a header file:

    mypackage/
    ├── header.py
    │   ├── from .mod1 import *
    │   └── from .mod2 import *
    ├── mod1.py
    │   ├── def func1(): return 1
    │   └── ...
    │
    ├── mod2.py
    │   ├── def func2(): return 2
    │   └── ...
    └── mod3.py
    

    And in mod3.py you can import header.py and use the functions in various ways:

    from .header import *
    val1 = func1()
    val2 = func2()
    
    from . import header
    val1 = header.func1()
    val2 = header.func2()
    
    from . import header as p
    val1 = p.func1()
    val2 = p.func2()