warvariuc
warvariuc

Reputation: 59604

Import parent module package

The directory structure:

[app]
    start.py
        import package1
    [package1]
        __init__.py
            print('Init package1')
            import module1
            import subpackage1
        module1.py
            print('package1.module1')
            import package1 # this works OK
        [subpackage1]
            __init__.py
                print('Init package1.subpackage1')
                import module1
            module1.py
                print('Init package1.subpackage1.module1')
                #from package1 import subpackage1 # ImportError: cannot import name subpackage1
                #from .. import subpackage1 # ImportError: cannot import name subpackage1
                #import . as subpackage1 # SyntaxError: invalid syntax
                import package1.subpackage1 as subpackage1 # AttributeError: 'module' object has no attribute 'subpackage1'

To avoid problems caused by circular imports in subpackage1.module1 i want to import module subpackage1 in order to refer to other modules from subpackage1 in form subpackage.module2. Because if i do from . import module2 the reference to module2 could not yet exist in subpackage1 when i try to this import.

I have tried 4 different approaches - none of them worked - see the comments in the code.

Any help?

Some time ago subpackage1 was top level package and it worked (see how this works in the source of package1.module1. Now, when i moved it one level down - i have this problem... I know that i can add package1 dir to sys.path, but that's ugly.

Upvotes: 3

Views: 1172

Answers (2)

warvariuc
warvariuc

Reputation: 59604

I used this hack, which worked for me:

#import package1.subpackage1 as subpackage1 # AttributeError: 'module' object has no attribute 'subpackage1'
subpackage1 = sys.modules[__name__.rpartition('.')[0]] # parent module

Or you can try this:

from package1 import subpackage1

which works in some cases: https://stackoverflow.com/a/24968941/248296

Upvotes: 2

ekhumoro
ekhumoro

Reputation: 120618

I'm not not exactly sure what you are trying to do, but your example might be a lot easier to understand if you used absolute imports and avoided putting code in __init__ modules.

Try something like this:

[app]
    start.py
        print('Start')
        from package1 import module1
    [package1]
        __init__.py
            print('Init: package1')
        module1.py
            print('Load: package1.module1')
            from package1.subpackage1 import module1
        [subpackage1]
            __init__.py
                print('Init: package1.subpackage1')
            module1.py
                print('Load: package1.subpackage1.module1')
                from package1 import subpackage1

After running start.py, you should get output like this:

Start
Init: package1
Load: package1.module1
Init: package1.subpackage1
Load: package1.subpackage1.module1

Upvotes: 1

Related Questions