1

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
rcallist
  • 21
  • 3
  • Does this answer your question? [How to access outer class from an inner class?](https://stackoverflow.com/questions/2024566/how-to-access-outer-class-from-an-inner-class) – fsimonjetz Mar 19 '22 at 17:22
  • I don't think that article addresses my specific example, as that article define an inner class within an outer class. I do not want the inner or child class defined within the outer or parent class, but I do want to instantiate one class within another class--but that is a difference construct. But maybe I didn't understand the article. – rcallist Mar 19 '22 at 21:16
  • @rcallist: Your analysis is entirely correct. – quamrana Mar 19 '22 at 21:20

1 Answers1

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.

quamrana
  • 37,849
  • 12
  • 53
  • 71
  • Very helpful. I was not aware of passing 'self' as an argument in the instantiation of the C object. One small issue, your approach requires referring to these B variables, from within C, as self.b.B, etc. as opposed to self.B. Are you sure there's not a way to use only self.B? The Backtrader module I referenced operates this way. Separately, I agree on your point about where to place the C instantiation code. Thanks much! – rcallist Mar 19 '22 at 21:10
  • No, with my code it can't be done as `self.B` since in `changeB(self)` you reassign: `self.B = 'B1'`. – quamrana Mar 19 '22 at 21:13