Skip to content

Instantly share code, notes, and snippets.

@tnodet
Last active February 10, 2021 12:13
Show Gist options
  • Select an option

  • Save tnodet/d65b43636f0c169c65a1ec98513888fc to your computer and use it in GitHub Desktop.

Select an option

Save tnodet/d65b43636f0c169c65a1ec98513888fc to your computer and use it in GitHub Desktop.
Property inheritance done right in Python 3
class A:
def __init__(self):
self._prop = "bonjour"
@property
def prop(self):
print("A.prop.getter")
return self._prop
@prop.setter
def prop(self, value):
print("A.prop.setter")
self._prop = value
class B(A):
"""Override getter and setter"""
@property
def prop(self):
print("B.prop.getter")
return super().prop # for getter, you can directly use super().prop
# return super(B, self.__class__).prop.fget(self) # although fget would work
@prop.setter
def prop(self, value):
print("B.prop.setter")
# super().prop = value # this doesn't work! (AttributeError: 'super' object has no attribute 'prop')
super(B, self.__class__).prop.fset(self, value) # for setter, you must use the fset method of the parent class's property
# If you want to override only the getter or setter (but not both), you have to reference the parent class's property in the decorator
class B1(A):
"""Override only getter"""
@A.prop.getter
def prop(self):
print("B1.prop.getter")
return super().prop
class B2(A):
"""Override only setter"""
@A.prop.setter
def prop(self, value):
print("B2.prop.setter")
super(B2, self.__class__).prop.fset(self, value)
# Note: don't use both '@ParentClass.prop.setter' and '@ParentClass.prop.getter' in a single child class,
# because if the parent class itself inherited the property and only defined either the getter or the setter,
# this can lead to the parent getter or setter not being called (the grandparent getter/setter is directly called).
a = A()
a.prop
# A.prop.getter
# 'bonjour'
a.prop = "au revoir"
# A.prop.setter
a.prop
# A.prop.getter
# 'au revoir'
b = B()
b.prop = "salut"
# B.prop.setter
# A.prop.setter
b.prop
# B.prop.getter
# A.prop.getter
# 'salut'
b1 = B1()
b1.prop = 'only getter'
# A.prop.setter
b1.prop
# B1.prop.getter
# A.prop.getter
# 'only getter'
b2 = B2()
b2.prop = 'only setter'
# B2.prop.setter
# A.prop.setter
b2.prop
# A.prop.getter
# 'only setter'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment