5

I have this structure:

.
└── module
    ├── __init__.py
    └── submodule
        ├── __init__.py
        ├── foo.py
        └── bar.py

In module.submodule.__init__.py I have this:

import foo
import bar

In module.submodule.foo.py I have this:

import very_heavy_third_party_module as vhtpm
...

I would like to import bar only, but I got slowed down by foo (let's imagine there is an ugly time.sleep(3) in both foo and module/__init__.py).

So my goal is to write this below without getting slowed down by other parts of my module:

from module.submodule.bar import saybar
saybar()

How can I just import saybar located in my submodule bar?

5
  • 1
    from module import submodule.bar.saybar ? Commented Nov 2, 2016 at 14:41
  • @Illusionist not really working. Have you tried from datetime import datetime.now ? Commented Nov 2, 2016 at 14:44
  • I don't know if this can be done but it looks like bar does not belong in that submodule. Commented Nov 2, 2016 at 14:46
  • 1
    You can't. In order to import a submodule you must import its package. If inside the __init__.py that defines the package you import all submodules you always end up importing all submodules and there's nothing you can really do to avoid this. To fix this: avoid putting the imports inside __init__.py, or just put those that are fast and leave the heavy module non-imported. Commented Nov 2, 2016 at 14:47
  • 1
    sys.path.append(r'path_to_module\module\submodule');import bar ??? Commented Nov 2, 2016 at 14:48

1 Answer 1

3

The only way to do import from bar without running foo is to remove import foo from module.submodule.__init__.py. This is because when you import a package/module in Python, all of the top-level code in that module (or __init__.py if importing a package) is run. When you run from module.submodule.bar import saybar, all of the top-level code in:

  • module.__init__.py
  • module.submodule.__init__.py
  • module.submodule.bar.py

is run. Since module.submodule.__init__.py contains import foo, foo is imported and all of its top-level code (including import very_heavy_third_party_module as vhtpm) is run as well, causing the slowdown.

A few possible solutions are:

  • Move as much code as possible out of __init__.py. It's a common practice to leave __init__.pys empty - if there's some functionality in there, you might want to consider moving it to its own module. Once the import lines are the only ones remaining, you can just remove them, since they make no difference with regards to namespacing.
  • Relocate the import vhtpm in foo.py down from the top-level (e.g. into a function that's called by something else in the module). This isn't very clean, but might work for you if you need the optimization.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.