swas
swas

Reputation: 79

Python best practice import submodule in submodule

I'm currently reading about Python's submodule in submodule imports and somehow I can't find a proper answer. Here is an example:

root/
     main.py
     moduleA/
             __init__.py
             log.py
     moduleB/
             __init__.py
             worker.py

I'd like to import log in worker by using import moduleA.log. And I'd like to import worker in main and use it there.

So far I've found the following solutions:

I've read that the sys.path hack is considered the best practice. But somehow it feels wrong.

So I'd like to know what is considered best practice by you.

Upvotes: 3

Views: 1885

Answers (3)

JE_Muc
JE_Muc

Reputation: 5774

You can use relative imports to solve this issue:

In main.py write

from .moduleB import worker

In worker.py:

from ..moduleA import log

One dot takes the current directory as beginning of the path, so .moduleB digs into the folder moduleB below the current dir.
Two dots moves one dir upwards, so ..moduleA in goes up to the root directory and then down to moduleA. Each additional dot is one directory up.
F.i. from . import ab would import ab.py from the same directory.
Packaging/installing a module is not necessary to do relative imports. But you have to import with from ..moduleA import log. Importing with import ..moduleA.log won't work with relative imports.

Upvotes: 2

Cyril D.
Cyril D.

Reputation: 363

I'll typically use a modulename.py file that contains all the imports, which I can refer to later:

With your structure:

root/
     __init__.py
     root.py
     modulea/
         __init__.py
         a.py
      moduleb/
         __init__.py
         b.py

The root.py would be:

from modulea.a import sleep, eat, breath
from moduleb.b import read, write, watch

such that I can later do

from package.root import sleep, read, watch

However, this requires having your package installed, which may not always be practical.

Upvotes: 0

Paritosh Singh
Paritosh Singh

Reputation: 6246

I personally prefer to change my current working directory and import just in case i ever run into this issue.

root/
     __init__.py
     root.py
     modulea/
             __init__.py
             a.py
     moduleb/
             __init__.py
             b.py

Given a setup like this,

a.py
def a():
    print("i am a")

And in b, just change current directory to root using either absolute or relative path via os.chdir

b.py

def b():
    print("i am b")

import os
os.chdir('..')
from modulea.a import a
a()

Running b.py prints i am a

The other options are out there, sys.path or PYTHONPATH modifications. Refer here

I do however also recommend avoiding such scenarios best you can as far as possible.

Upvotes: -1

Related Questions