bend or redirect a class method and then call it again

Jeff Shannon jeff at ccvcorp.com
Thu Jul 22 17:24:28 EDT 2004


Francesco wrote:

>>What's the point of this extra 'NewStatusText' method?  You're already 
>>overriding SetStatusText.  Without the NewStatusText and the setattr() 
>>call, when someone calls SomePluginObject.SetStatusText(), it will call 
>>your new version rather than the wx.Frame (or DrFrame) version 
>>    
>>
>
>but not from drFrame itself; that is the point.
>  
>

Unless I'm misunderstanding your intent, then yes, from drFrame itself.

Every Plugin object is also a drFrame object (and a wx.Frame object).  
*Every* SetStatusText() call on any such object will use the 
most-derived version of SetStatusText(),  i.e. the Plugin version.  Even 
the calls that are part of the drFrame class definition.  The *only* 
exception to this is if, instead of using self.SetStatusText(), you're 
using drFrame.SetStatusText(self, ...) -- in that case, you've 
explicitly asked for the drFrame version.  But if you have, for example, 
something like this:

class drFrame(wx.Frame):
    def do_something(self, *args):
        # [....]
        self.SetStatusText("New Status")

then despite the fact that this is a drFrame method, and doesn't know 
anything about the Plugin derived class, it will indeed result in the 
Plugin version of SetStatusText() being called.  That's the whole 
*point* of inheritance.

I can see two cases where what you're doing would have some effect that 
doesn't replicate normal method resolution order, and to be honest I 
think that using either case is a sign of some very questionable design 
decisions and definitely violates the guiding principles of OO and 
inheritance.  One case would be that there are indeed places where the 
drFrame.SetStatusText(self, ...) is explicitly called, and you're trying 
to override those explicit requests.  This is bad form -- an explicit 
request should be honored, because there's probably a real reason for 
it.  The other case is where you are trying to modify the behavior of 
all drFrame instances, including those which are *not* also Plugin 
instances.

In both cases, you're doing something magic behind your back.  It's much 
better to do that kind of stuff up front, where it can be seen.  (For 
instance, in the second case, simply derive an intermediate class from 
drFrame, and then derive Plugin from that.  Use the intermediate class 
anywhere where you'd currently use drFrame, and you're set.)  I would 
bet that there's a more straightforward way of accomplishing what you 
actually want to do, without resorting to this kind of sleight-of-hand.  
(I trust sleight-of-hand in programs about as much as I trust 
sleight-of-hand in people who're holding my wallet -- there may be cases 
where it's justified and where it can be trusted, but I'm not going to 
hand my wallet to just anyone...)

Jeff Shannon
Technician/Programmer
Credit International




More information about the Python-list mailing list