Python 3 here, just in case it's important.
I'm trying to properly understand how to implement inheritance when @property
is used, and I've already searched StackOverflow and read like 20 similar questions, to no avail because the problems they are trying to solve are subtly different. This is the code I'm using for testing:
class Example:
def __init__(self):
self.__data = None
@property
def data(self):
return self.__data
@data.setter
def data(self, data):
self.__data = data
class Example2(Example):
def __init__(self):
super().__init__()
@property
def data(self):
return super().data # Works!
@data.setter
def data(self, data):
data = '2' + data
#Example.data = data # Works, but I want to avoid using the parent name explicitly
#super().data = data # Raises AttributeError: 'super' object has no attribute 'data'
#super().data.fset(self, data) # Raises AttributeError: 'NoneType' object has no attribute 'fset'
#super(self.__class__, self.__class__).data = data # Raises AttributeError: 'super' object has no attribute 'data'
super(self.__class__, self.__class__).data.fset(self, data) # Works!
a = Example2()
a.data = 'element a'
print(a.data)
What I can't understand is why super().data
works in Example2
getter, but not in setter. I mean, why in the setter a class bound method is needed, but in the getter an instance bound method works?
Could anyone please point me to an explanation or explain why I'm getting AttributeError
in three of the five different calls I'm testing?
Yes, I know, I could use Example.data
in the setter, but that's not needed in the getter and a) I would prefer not to use the parent class name explicitly if possible and b) I don't understand the asymmetry between getter and setter.