-1

To avoid circular imports, one can use import x and then use x.func each time. (cf. Circular (or cyclic) imports in Python ). (In my case, I have no other choice actually)

However, when x is for example a.b.c.d.e, then you get a non-negligible overhead (in addition to the readability problems), especially if your function is called repetitively. I would like to know if there is some kind of mechanism to define shortcuts like E = a.b.c.d.e when the imports are resolved ? (or something to avoid the lookup eachtime)

Note : on pypy, there is no performance differences but on CPython, you can get ×2 improvement between a.A() and a.b.c.d.e.f.g.h.A()

EDIT about the import ... as ... solution, this is the trace I get (I think it will be clearer than any explication I could give) :

  File "MyApp/__init__.py", line 3, in <module>
    import MyApp.core
  File "MyApp/core.py", line 3, in <module>
    import MyApp.formatters.ASCIIFormatter as _F
  File "MyApp/formatters/__init__.py", line 2, in <module>
    import MyApp.formatters.ASCIIFormatter as ASCIIFormatter
  File "MyApp/formatters/ASCIIFormatter.py", line 2, in <module>
    import MyApp.core as _C
AttributeError: module 'MyApp' has no attribute 'core'
hl037_
  • 3,520
  • 1
  • 27
  • 58
  • *"the best practice in python"* - gonna need a citation. – Peter Wood Jun 05 '17 at 11:57
  • @PeterWood done – hl037_ Jun 05 '17 at 12:00
  • 1
    That's not best practice, just how to work around having circular imports. The best way to avoid circular imports is to not have them. Organise your dependencies properly, reduce module responsibilities, use abstract over concrete types, etc, etc. – Peter Wood Jun 05 '17 at 12:07
  • actually, The problem raise because I had at the origin only one module of over 5000 lines, and I wanted to split it (code doing display, computation, UI etc.) so there are some cross dependencies – hl037_ Jun 05 '17 at 12:12

1 Answers1

0

You can set an alias when importing a module:

import a.b.c.d.e as E

The code you posted would work as well, but it's not as pretty:

import a.b.c.d.e
E = a.b.c.d.e
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • Won't work : because of the circular import problem, `a` has no attribute `b` yet ( or one of the submodules...) – hl037_ Jun 05 '17 at 12:02
  • 1
    @hl037_ Then how are you doing your imports? Your question is asking how to avoid the expensive name lookup, it doesn't mention anything about failing imports. – Aran-Fey Jun 05 '17 at 12:05
  • suppose that all the code was first in a very huge `a` module, and maintaining it was a hell, so it was split in submodules. However, some functions of `a.b.c.d.f` calls functions of `a`, and some functions of `a` need some stuff in `a.b.c.d.f` so in `a`, you have an `import a.b.c.d.f` and in `a.b.c.d.f`, you have `import a` – hl037_ Jun 05 '17 at 12:10
  • @hl037_ Then I don't see what's preventing you from changing `import a.b.c.d.f` to `import a.b.c.d.f as F`. – Aran-Fey Jun 05 '17 at 12:14
  • you're right, the example was poorly chosen, I added the traceback I get in my project in the question – hl037_ Jun 05 '17 at 12:24