made a small script:
@dataclass
class superproperty:
g:"func"=None
s:"func"=None
d:"func"=None
def __set_name__(self, owner, name):
iter=(b for b in owner.__mro__ if hasattr(b,name))
next(iter)
base=next(iter)
orig=getattr(base,name)
if self.g is not None:orig=orig.getter(self.g)
if self.s is not None:orig=orig.setter(self.s)
if self.d is not None:orig=orig.deleter(self.d)
setattr(owner,name,orig)
def getter(self,f):
self.g=f
return self
def setter(self,f):
self.s=f
return self
def deleter(self,f):
self.d=f
return self
usage:
>>> class A():
... @property
... def f(self):
... print("Ag")
... @f.setter
... def f(self,nvalue):
... print("As")
...
...
>>> class B(A):
... @superproperty
... def f(self):
... print("Bg")
...
...
>>> class C(B):
... @superproperty
... def f(self):
... print("Cg")
... @f.deleter
... def f(self):
... print('Cd')
...
...
>>> A().f
Ag
>>> A().f=3
As
>>> B().f
Bg
>>> B().f=3
As
>>> C().f
Cg
>>> C().f=3
As
>>> del C().f
Cd