Relative importing modules from parent folder subfolder
Asked Answered
O

3

53

Given a directory structure like this

main/
    common/
        foo.py
    A/
        src/
            bar.py

How can I use Python's relative imports to import foo from bar? I've got a working solution by adding it to the path, but this is ugly. Is there a way to simply do with a single import in Python 2.7?

This is a more complex version of this question:

Importing modules from parent folder

Oligosaccharide answered 27/12, 2012 at 15:58 Comment(0)
H
59

The correct relative import would be this:

from ...common import foo

However, relative imports are only meant to work within one package. If main is a package, then you can use relative imports here. If main is not a package, you cannot.

Thus, if you're running a script in /main/ and doing something like import A.src.bar, then that relative import will fail with "Attempted relative import beyond toplevel package". This is because the relative import is trying to import something outside of the toplevel package A.

However, if you're running a script in / and doing something like import main.A.src.bar, then that relative import will succeed because main is now a package. In that case, the following two would be equivalent:

from ...common import foo
from main.common import foo

To answer your comment: the meaning of the . doesn't change depending on where the script was run from, it changes depending on what the package structure is.

Homocercal answered 27/12, 2012 at 16:6 Comment(1)
so, what is a solution for first case you said?Winfordwinfred
P
0

In order to use relative imports, you have to have a package. In this example I think 'main' folder is the best candidate to be the top level package. Make a __init__.py inside 'main' folder and put the following code inside it to make it the top level folder in package:

__package__ = ''

Now you can use relative imports:

from ...common import foo
Pursuant answered 9/5, 2023 at 16:51 Comment(0)
F
0

If you are working with framework that uses OPSEC practices to limit the top-level-project of scripts but you need to import a local library from another place without copy-paste the same library for every script... (the reason cause im here) You can bypass the problem with a simbolic link to the folder that contains the code.

4 your example its like:

cd path2/A
ln -s path2/main/common common

then you can import in bar.py with

from A.common.foo import class

But if you do this instead of creating __init__.py's when its required then you have my intense dissaproval.

Frodeen answered 26/9, 2023 at 11:17 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Pickett

© 2022 - 2024 — McMap. All rights reserved.