Reputation: 6216
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?
Upvotes: 9
Views: 16778
Reputation: 365767
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
.
Upvotes: 2
Reputation: 363607
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
Upvotes: 10
Reputation: 15944
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
).
Upvotes: 5