How to change variable of main class from inherited class?
<p>I need to change object variable directly from inherited class.
Here is my code example: </p>

<pre><code>class A(object):
    def __init__(self,initVal=0):
        self.myVal = initVal

    def worker(self):
        self.incrementor = B()
        self.incrementor.incMyVal(5)        

class B(A):
    def incMyVal(self,incVal):
        super().myVal += incVal

obj = A(5)
print(obj.myVal)

obj.worker()
print(obj.myVal)
</code></pre>

<p>But it doesn't work:</p>

<pre><code>AttributeError: 'super' object has no attribute 'myVal'
</code></pre>

<p>I also tried to use global/nonlocal keywords with my variable in B class, but no luck.</p>

<p>In my main case, the <code>B</code> class is an event handler. And it should change the attribute of an object when an event fires. So I'm not able to use <code>return</code> in the <code>incMyVal</code> method.</p>

<p><code>super()</code> can only search for <em>class attributes</em> in the class MRO, not instance attributes. <code>myVal</code> is set on an <em>instance</em> of the class, not on a class itself.</p>

<p>There is only ever one instance; it doesn't matter if code from class <code>A</code> or a derived class is altering attributes on an instance, it is just one namespace.</p>

<p>However, in your case, you shouldn't even be using inheritance. You are trying to use an <em>independent, second instance</em> to alter the attributes of an instance of <code>A</code>. Class inheritance doesn't give you access to <em>instances</em> of the base class like this.</p>

<p>Refactor <code>B</code> to take an instance of <code>A</code>, then act on that instance:</p>

<pre><code>class B:
    def __init__(self, ainstance):
        self.ainstance = ainstance
    def incMyVal(self, incVal):
        self.ainstance.myVal += incVal
</code></pre>

<p>Note that <code>B</code> is not a subclass of <code>A</code> here; it is not a (specialised) object of the same type at all; it is a different kind of thing, something that increments attributes of another object.</p>

<p>Pass in the instance when you create an instance of <code>B</code>:</p>

<pre><code>def worker(self):
    self.incrementor = B(self)
    self.incrementor.incMyVal(5)        
</code></pre>

<p>This does create a circular reference, which can keep objects alive for longer than perhaps needed. You may want to use a <a href="https://docs.python.org/3/library/weakref.html" rel="nofollow">weak reference</a> instead:</p>

<pre><code>import weakref

class B:
    def __init__(self, ainstance):
        self.ainstance_ref = weakref.ref(ainstance)
    def incMyVal(self, incVal):
        ainstance = self.ainstance_ref()
        if ainstance is not None:
            ainstance.myVal += incVal
</code></pre>

<p>Now <code>B</code> instances only hold a weak reference to their <code>A</code> instance, and will do nothing if that instance no longer exists.</p>

python python-3.x