9

One way is to use import x, without using "from" keyword. So then you refer to things with their namespace everywhere.

Is there any other way? like doing something like in C++ ifnotdef __b__ def __b__ type of thing?

Dexter
  • 6,170
  • 18
  • 74
  • 101
  • 2
    Don't have circular dependencies, create z by combining dependencies of x in y, and dependecies of y in x – Esailija Dec 13 '12 at 20:13
  • This post is a duplicate: http://stackoverflow.com/questions/744373/circular-or-cyclic-imports-in-python – alinsoar Dec 13 '12 at 20:14
  • 2
    @alinsoar It's not an exact duplicate -- that question asked what happens when you have circular imports; and this question asks for techniques to avoid them. – Edward Loper Dec 13 '12 at 20:22
  • It is about 2 modules that import each other, i.e. circular. I did not watch if the solution. The problem is the same. – alinsoar Dec 13 '12 at 20:24
  • Are you trying to do `from foo import bar`, or `from foo import *`? Because if it's the latter, the answer is, don't do that. There are only a few special cases (outside of quick&dirty scripts or interactive sessions, where circular imports won't come up) where you want to do that, and I can't think of any case where `from foo import *` and mutual dependence both make sense. – abarnert Dec 13 '12 at 20:26
  • Also, if what you're trying to accomplish is to be able to type `f` instead of `x.f`, why? Is it just because `x` is actually a 40-character-long nested module name, or because you want to make Python feel more like a different language, or for some real reason (e.g., you want to `try` to `from json import loads` and define a local `loads` if it fails)? – abarnert Dec 13 '12 at 20:39

3 Answers3

10

Merge any pair of modules that depend on each other into a single module. Then introduce extra modules to get the old names back.

E.g.,

# a.py
from b import B

class A: whatever

# b.py
from a import A

class B: whatever

becomes

# common.py
class A: whatever
class B: whatever

# a.py
from common import A

# b.py
from common import B
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 30
    This forces one to start declaring everything in `common.py` rather than `a.py` and `b.py`. Not a good solution IMHO. – Nick Oct 02 '13 at 00:45
5

Circular imports are a "code smell," and often (but not always) indicate that some refactoring would be appropriate. E.g., if A.x uses B.y and B.y uses A.z, then you might consider moving A.z into its own module.

If you do think you need circular imports, then I'd generally recommend importing the module and referring to objects with fully qualified names (i.e, import A and use A.x rather than from A import x).

Edward Loper
  • 15,374
  • 7
  • 43
  • 52
  • 3
    What if one is doing some explicit type checking? I am trying to do that right now so I can provide a very detailed error message, rather than some obfuscated traceback that my customers don't understand. – Nick Oct 02 '13 at 00:47
2

If you're trying to do from A import *, the answer is very simple: Don't do that. You're usually supposed to do import A and refer to the qualified names.

For quick&dirty scripts, and interactive sessions, that's a perfectly reasonable thing to do—but in such cases, you won't run into circular imports.

There are some cases where it makes sense to do import * in real code. For example, if you want to hide a module structure that's complex, or that you generate dynamically, or that changes frequently between versions, or if you're wrapping up someone else's package that's too deeply nested, import * may make sense from a "wrapper module" or a top-level package module. But in that case, nothing you import will be importing you.

In fact, I'm having a hard time imagining any case where import * is warranted and circular dependencies are even a possibility.

If you're doing from A import foo, there are ways around that (e.g., import A then foo = A.foo). But you probably don't want to do that. Again, consider whether you really need to bring foo into your namespace—qualified names are a feature, not a problem to be worked around.

If you're doing the from A import foo just for convenience in implementing your functions, because A is actually long_package_name.really_long_module_name and your code is unreadable because of all those calls to long_package_name.really_long_module_name.long_class_name.class_method_that_puts_me_over_80_characters, remember that you can always import long_package_name.really_long_module_name as P and then use P for you qualified calls.

(Also, remember that with any from done for implementation convenience, you probably want to make sure to specify a __all__ to make sure the imported names don't appear to be part of your namespace if someone does an import * on you from an interactive session.)

Also, as others have pointed out, most, but not all, cases of circular dependencies, are a symptom of bad design, and refactoring your modules in a sensible way will fix it. And in the rare cases where you really do need to bring the names into your namespace, and a circular set of modules is actually the best design, some artificial refactoring may still be a better choice than foo = A.foo.

abarnert
  • 354,177
  • 51
  • 601
  • 671