Skip to content Skip to sidebar Skip to footer

Instantiating Two Classes With References To Each Other

I have two classes, B and C. I want to instantiate B with C reference and C with B reference. I could add a setter method, but was wondering if I can do it in the __init__ stage or

Solution 1:

It is not possible within __init__ directly due to a chicken and egg situation. However, it is possible in one assignment statement:

>>> class A:
...     pass
... 
>>> class B:
...     pass
... 
>>> a, b = b.a, a.b = A(), B()
>>> a.b is b
True
>>> b.a is a
True

This relies on the fact that Python evaluates assignments left to right.

It is not thread safe; if you need to guarantee that the references exist in a threaded application then you'll want to use a mutex to handle the possible race conditions. The GIL works at the opcode level, which is a finer-grained resolution than lines of Python code.


Solution 2:

You could do it in __init__ if you make one of the class initializers take an object of the other class:

>>> class B:
...    def __init__(self):
...       self.c = C(self)
...
>>> class C:
...    def __init__(self, b):
...       self.b = b
...
>>> b = B()
>>> c = b.c
>>> b.c
<__main__.C object at 0x107a4f6d8>
>>> b.c.b.c
<__main__.C object at 0x107a4f6d8>
>>> b.c.b.c.b
<__main__.B object at 0x107a60e80>
>>> b
<__main__.B object at 0x107a60e80>
>>> c
<__main__.C object at 0x107a4f6d8>
>>> c.b
<__main__.B object at 0x107a60e80>
>>> b.c
<__main__.C object at 0x107a4f6d8>
>>> b.c.b.c
<__main__.C object at 0x107a4f6d8>
>>> c.b.c.b
<__main__.B object at 0x107a60e80>

Or even without any arguments to __init__:

>>> class B:
...     def __init__(self):
...         self.c = C()
...         self.c.b = self
...
>>> class C:
...     pass
...
>>> b = B()
>>> c = b.c
>>> b
<__main__.B object at 0x10835c048>
>>> c
<__main__.C object at 0x1085ccac8>
>>> b.c
<__main__.C object at 0x1085ccac8>
>>> c.b
<__main__.B object at 0x10835c048>
>>> b.c.b.c.b
<__main__.B object at 0x10835c048>

Post a Comment for "Instantiating Two Classes With References To Each Other"