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:

>>>classA:...pass...>>>classB:...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:

>>>classB:...def__init__(self):...      self.c = C(self)...>>>classC:...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__:

>>>classB:...def__init__(self):...        self.c = C()...        self.c.b = self...>>>classC:...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"