method overriding trick
David Ascher
da at ski.org
Thu Nov 11 12:22:30 EST 1999
On Thu, 11 Nov 1999, Jeremy Hylton wrote:
> Overriding methods of a base class is a little clunky in Python. You
> need to explicitly name the base class that implements the method, and
> you call its as an unbound method, passing self as the first argument.
> Example: Base.aMethod(self, arg)
>
> I was reading about MzScheme the other day (a Scheme variant with
> object and interface support), and noticed that the MzScheme approach
> translates well to Python. MzScheme class defintions allow a rename
> declarations that create a name in the class being defined that is
> bound to a name in a superclass. In Python, rename is just called
> assignment.
>
> class Base:
> def aMethod(self, arg):
> return arg * 2
>
> class Derived1(Base):
> super_aMethod = Base.aMethod
>
> def aMethod(self, arg):
> return self.super_aMethod(arg) + 1
>
> I haven't seen this strategy for overriding mentioned before, although
> I did not search the list archives. When I described it to Guido, he
> said, "Does that work?" Has anyone used this trick before?
>
> It doesn't solve the must-name-the-base-class problem, but it helps
> manage it better. If you keep the override assignments at the top of
> the class statement, then you only have one place to look in each
> class when the inheritance hierarchy changes.
Cute! You can also make it a mixin, along the lines of:
import new
class Mixin:
def __getattr__(self, k):
if k[:len('super_')] == 'super_':
for b in self.__class__.__bases__:
m = getattr(b, k[len('super_'):], None)
if m:
return new.instancemethod(m, self, self.__class__)
else:
raise AttributeError, k
else:
raise AttributeError, k
class Base(Mixin):
def f(self):
print 'Base.f'
class Sub(Base):
def f(self):
print 'Sub.f'
self.super_f()
s = Sub()
s.f()
Not especially fast, of course, but doesn't require as much human memory
load.
--david
More information about the Python-list
mailing list