Cooperative class tree filtering
Alberto Berti
alberto at metapensiero.it
Thu Oct 12 19:56:37 EDT 2017
Sorry, i've made a mistake in the second C body, it's written like:
>>>>> "me" == Alberto Berti <alberto at metapensiero.it> writes:
me> I've tried some variants of the 'super()' trick, that sometimes seems to
me> change behavior if it's written like that or like super(type(self),
me> self) in no clear (to me, and I failed to find extensive doc on
me> super()'s behavior) way, with things that stop working if mixins are
me> involved (even if the mixins do not reimplement the methods involved
me> here). Eventually i ended implementing a decorator:
me> from functools import partial, wraps
me> class delegate_super:
me> """A method decorator that delegates part of the computation to the same
me> method on the ancestor class."""
me> _name = None
me> _owner = None
me> def __init__(self, meth):
me> self._meth = meth
me> @wraps(meth)
me> def wrapper(*args, **kwargs):
me> return self.delegator(*args, **kwargs)
me> self.wrapper = wrapper
me> def __get__(self, instance, owner):
me> return partial(self.wrapper, instance)
me> def __set_name__(self, owner, name):
me> self._owner = owner
me> self._name = name
me> def delegator(self, instance, *args, **kwargs):
me> result = self._meth(instance, *args, **kwargs)
me> if result is None:
me> result = getattr(super(self._owner, instance), self._name)(
me> *args, **kwargs)
me> return result
me> class A:
me> def filter(self, element):
me> # the default implementation always returns True
me> return True
me> class B(A):
me> @delegate_super
me> def filter(self, element):
me> if element == 'foo':
me> return True
me> elif element == 'bar':
me> return False
me> class C(B):
me> @delegate_super
me> def filter(self, element):
me> if element == 'bar':
me> return True
me> else:
me> return super().filter(element)
The correct version is:
class C(B):
@delegate_super
def filter(self, element):
if element == 'bar':
return True
More information about the Python-list
mailing list