3

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.

warvariuc
  • 57,116
  • 41
  • 173
  • 227

2 Answers2

2

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

Community
  • 1
  • 1
warvariuc
  • 57,116
  • 41
  • 173
  • 227
1

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
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Thanks for the response, but i need to import some names from `module1` to expose them in `subpackage1.__init__`. Also i am importing modules `subpackage1.__init__` because there are several modules in `subpackage1` and i need to import them in a certain order. – warvariuc Nov 06 '11 at 13:10
  • @warvariuc. In general, putting code in `__init__` modules should be avoided. Needing to import modules in a specific order also has a bad code smell. It sounds like you need to split your modules up so that functionality can be shared between the modules more efficiently. – ekhumoro Nov 06 '11 at 15:46
  • i would like to do it better, but don't know how. As for code in `__init__` as frequently see this used in other projects - (for example scrapy). Otherwise, why you need `__init__` at all? – warvariuc Nov 06 '11 at 16:20
  • @warvariuc. The `__init__.py` files are needed to make python treat a directory as (part of) a package. They are usually left empty, but may sometimes contain some package initialization code. Although other code _can_ be put in them, that is not their intended purpose, and so many (but obviously not all) python coders tend to avoid using them in that way. Why do you think you need to use them? What specific problem are you trying to solve? – ekhumoro Nov 06 '11 at 16:54
  • i am importing some global variables from submodules into package namespace – warvariuc Nov 06 '11 at 19:33