Jeffrey Barish wrote: > Suppose that there are two classes defined as follows: > > class A(object): > def f1(self): > print 'In A.f1, calling func' > self.func() > > def func(self): > print 'In A.func' > > class B(A): > def func(self): > print 'In B.func, calling A.f1' > A.f1(self) > > Class A was defined by someone else or it comes from a library, so I have no > prior information about what is in it. I subclass A to add some new > functionality, and I call the new function "func". The function B.func > uses A.f1, but unbeknownst to me, A.f1 uses A.func. Unfortunately, class B > overrides func, so the call in A.f1 to self.func actually invokes B.func, > resulting in this case in an infinite loop. Is there a way from B to > specify that A should use its own version of func and ignore the version in > B? I know that I could rename A.func to avoid the name clash, but since A > is actually in a library, I will lose that change when I upgrade the > library. I could rename B.func, but there is already a bunch of code that > calls it so I would have to update all the calls. That seems like the > correct solution, though. The other possibility is to use composition > rather than subclassing: > > class B: > def func(self): > print 'In B.func, calling A.f1' > a = A() > a.f1() > > but then B does not inherit other functions of A that I would like to use. > It struck me that this must be a common problem in OOP, so I'm wondering > whether there is a simple solution that I am missing.
If you insist on this (I find silly) version, I'd suggest you want to use "has-a" rather than "is-a" relationship between B and A class A(object): def f1(self): print 'In A.f1, calling func' self.func() def func(self): print 'In A.func' class B(object): def __init__(self, *args, **kwargs): self._a = A(*args, **kwargs) def func(self): print 'In B.func, calling A.f1' self._a.f1() But, you could use this (I think ill-advised) technique if you need a special-case work-around: class Bb(A): def __init__(self, *args, **kwargs): super(Bb, self).__init__(*args, **kwargs) self._recursed_func = 0 def f1(self): self._recursed_func += 1 try: return super(Bb, self).f1() finally: self._recursed_func -= 1 def func(self): if self._recursed_func: return super(Bb, self).func() print 'In B.func, calling A.f1' self.f1() --Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list