Reputation: 3130
I have two tightly-coupled Python classes that need references to each other (at the class, not instance, level). How can I resolve the circular imports? Ideally I'd like to be able to make it work either within the same module or between two distinct modules, but I'll settle for one or the other.
# yin_yang.py
class MyYin(Yin):
__yang__ = MyYang
class MyYang(Yang):
__yin__ = MyYin
Upvotes: 4
Views: 849
Reputation: 6719
While @phillip-martin's response is the most pythonic one, there is an alternative way to accomplish the task:
from werkzeug import LocalProxy
class MyYin:
__yang__ = LocalProxy(lambda: MyYang)
foo = 42
class MyYang:
__yin__ = LocalProxy(lambda: MyYin)
bar = 9002
print(MyYin.__yang__.bar)
print(MyYang.__yin__.foo)
And the magic behind LocalProxy
trick comes from overriding all the __getattr__
, __setattr__
, __etc__
methods. Check it out in the werkzeug repo.
Upvotes: 2
Reputation: 70003
When the Python interpreter finds a class declaration, it creates a new scope and executes the code inside the class in this code block, i.e., all class variables are instantiated when the class declaration is executed.
You can avoid this in a really simple manner:
class MyYin(Yin):
pass
class MyYang(Yang):
__yin__ = MyYin
MyYin.__yang__ = MyYang
or
class MyYang(Yang):
pass
class MyYin(Yin):
__yang__ = MyYang
MyYang.__yin__ = MyYin
Upvotes: 0
Reputation: 1970
You could set the class attributes for one or both classes after they have been declared.
class MyYin(Yin):
pass
class MyYang(Yang):
__yin__ = MyYin
MyYin.__yang__ = MyYang
Upvotes: 5