Python Forum

Full Version: Getter/Setter : get parent attribute, but no Getter/Setter in parent
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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
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
Thank you for your clear explanation.