2

I have two python modules, a.py and b.py, both of which are in lib/ relative to the current directory. Suppose each module needs the functionality of the other.

a.py:

import lib.b
...

b.py:

import lib.a
...

The above example works with

PYTHONPATH=./lib python -c 'from lib import a, b'

However, if I switch the imports in a.py and b.py to from lib import b and from lib import a, respectively, the above Python command terminates with ImportError.

Could someone please explain why this breaks? I'm not trying to import any member from either a or b. (In that case I would be importing from an uninitialized module, as the question referenced below points out.)

Reference:

  1. python circular imports once again (aka what's wrong with this design)
Community
  • 1
  • 1
mxxk
  • 9,514
  • 5
  • 38
  • 46
  • See: http://stackoverflow.com/questions/11974395/import-error-what-is-going-on/ – warvariuc Mar 14 '14 at 06:26
  • 1
    -1 -- "works" and "breaks" don't have a meaning. Please specify what do you mean by providing a runnable example that demonstrates the behaviour. Also, if you get an error, you should post *all* the output you get and if you get an unexpected result you should post both the expected and actual result you get. – Bakuriu Mar 14 '14 at 10:15
  • +1: I can reproduce the issue. @Bakuriu: run [`test_from_vs_import.py`](https://github.com/zed/circular-import-vs-from) – jfs Mar 14 '14 at 13:53

2 Answers2

1

Since there did not seem to be a direct way to address the circular import, I went with a workaround.

In my actual use case, module a imported module b only to call the function b.fn, so I decided to put fn in a third module c and import c instead:

c.py

def fn():
  ...

b.py

from lib import a
from lib import c
...
# Explicitly assign `fn` into this module.
fn = c.fn

(The above could also be done with from lib.c import fn, but I prefer the explicit version.)

a.py

from lib import c
...

That way, the circular import between a and b is gone, and any additional modules that import b can use b.fn directly.

mxxk
  • 9,514
  • 5
  • 38
  • 46
0

in your lib folder there is a __init__.py file? If yes you have 2 possibility:

1) __init__.py is empty and you can use from lib import a,b

a.foo b.bar

2) in your __init__.py there are istructions import a,b in this case you can write

import lib.a as a import lib.b as b

hope this help you

archetipo
  • 579
  • 4
  • 10
  • It is incorrect. [Empty `__init__.py` does not help](http://stackoverflow.com/questions/22397610/python-circular-import-from-lib-import-module-vs-import-lib-module#comment34067749_22397610) – jfs Mar 14 '14 at 14:05
  • `lib/__init_py` is empty. I can import `a` and `b` in this file, but it doesn't help with the circular import problem. Moreover, I'd like to avoid adding every package under `lib/` to `lib/__init__.py`. – mxxk Mar 14 '14 at 23:36