Python Forum
Getter/Setter : get parent attribute, but no Getter/Setter in parent - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Getter/Setter : get parent attribute, but no Getter/Setter in parent (/thread-26664.html)



Getter/Setter : get parent attribute, but no Getter/Setter in parent - nboweb - May-08-2020

Hi all,

Trying to understand getter/setter...

The following code works fine.
B.x always returns 1 more than A.x (only interested in getters in this example)

class A(object):
    def __init__(self):
        self._x = 100

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, v):
        pass


class B(A):
    
    @property
    def x(self):
        return super().x + 1

    @x.setter
    def x(self, v):
        pass

testA = A()
testB = B()
print(testA.x)
print(testB.x)
Result :
100
101

Now, imagine A is slightly changed
--> A has no more getter/setter, and its attribute self._x is now self.x
The following code does not work anymore.

class A(object):
    def __init__(self):
        self.x = 100

class B(A):
    
    @property
    def x(self):
        return super().x + 1

    @x.setter
    def x(self, v):
        pass

testA = A()
testB = B()
print(testA.x)
print(testB.x)
Result :
AttributeError: 'super' object has no attribute 'x'

I understand that the interpreter looks for a "x getter" in A, but there is none.
How to implement this, so that I still can use testB.x to get the value +1, WITHOUT CHANGING A.

Obviously I could create a function get_x_plus_1() in B, but it is not the purpose. I want textB.x

Any idea ?
Thanks for your help, much appreciated.
Best regards,
Nico


RE: Getter/Setter : get parent attribute, but no Getter/Setter in parent - deanhystad - May-09-2020

There is definitely a catch-22 going on. You cannot get A.a from inside B because you did not call A.__init__ so there is no A.a. And if you give B an __init__ that calls A.__init__ you cannot define property "a" because B already has an attribute "a".
class A:
    def __init__(self):
        self.a = 0

class B(A):
    def __init__(self):
        super().__init__()
        
    @property
    def a(self):
        return  1
print(B().a)
Output:
Traceback (most recent call last): File "C:\Users\djhys\Documents\Python\Musings\page1.py", line 14, in <module> print(B().a) File "C:\Users\djhys\Documents\Python\Musings\page1.py", line 7, in __init__ super().__init__() File "C:\Users\djhys\Documents\Python\Musings\page1.py", line 3, in __init__ self.a = 0 AttributeError: can't set attribute
Because this is the same as
class B:
    def __init__(self):
        self.a = 0
        
    @property
    def a(self):
        return  self.a + 1
The obvious answer is to write your own language that allows things like this. Alternately you can write python code that follows the rules
class A:
    def __init__(self):
        self.a = 0

class B(A):
    def __init__(self):
        super().__init__()
        
    @property
    def b(self):
        return  self.a + 1

    @b.setter
    def b(self, value):
        self.a = value



RE: Getter/Setter : get parent attribute, but no Getter/Setter in parent - nboweb - May-11-2020

Thank you for your clear explanation.