'How to share variables between nested class objects using self nomenclature

Suppose I have class B and I want to instantiate class C within class B (hence my use of nested in the title, though I don't know if that's a technically correct term). I also want the code within class C to be able to reference and use variables within class B using the 'self' nomenclature. I know variables can be referenced or shared by prefixing variables with the class B instance name (such as if I had instantiated class B with b = B() then class C could refer to variables within the class B instance using b.xyz, etc. But I want to do so using self.xyz, etc. Following is as close as I can get, but I'm not quite successful. I am using inheritance b/c that gets me close, but I have seen this done in another program/module (Backtrader if you are familiar) in a way that might not use inheritance. In the example below, I am setting self.B to 'B' within class B and am able to reference self.B within my C class instance. However, I then change self.B to 'B1' within the class B instance, but this is not seen by my class C instance, as proven by the fact that the last line of code should print 'B1' but it prints 'B'. It appears that my inheritance code simply copies the class B variables to class C through inheritance; I want to share those variables. Thanks in advance.

class B():
    def __init__(self):
        print('B init')
        self.B = 'B'

    def createC(self):
        self.cc = C()

    def changeB(self):
        self.B = 'B1'

class C(B):
    def __init__(self):
        super().__init__()
        print('C init')
        self.C = 'C'
        print(self.B)

    def next(self):
        print('C next')
        print(self.B)

b = B()
b.createC()
b.cc.next()
b.changeB()
print(b.B)
b.cc.next()  # this should print 'B1' but prints 'B'

My output appears as below. The last 'B' printed should be 'B1'.

B init
B init
C init
B
C next
B
B1
C next
B


Solution 1:[1]

I think that inheritance is a red herring for you. I think you just need for two instances to refer to each other:

class B():
    def __init__(self):
        print('B init')
        self.B = 'B'

    def createC(self):
        self.cc = C(self)

    def changeB(self):
        self.B = 'B1'

class C():
    def __init__(self, B):
        print('C init')
        self.C = 'C'
        self.b = B
        print(self.b.B)

    def next(self):
        print('C next')
        print(self.b.B)

b = B()
b.createC()
b.cc.next()
b.changeB()
print(b.B)
b.cc.next()

Output:

B init
C init
B
C next
B
B1
C next
B1

Still, technically, you should not be instantiating a C inside the createC() method since, if you don't call that method, you don't create the cc attribute.

Better would be to have self.cc = C(self) at the end of the __init__(self) of the B class.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 quamrana