bend or redirect a class method and then call it again

Franz Steinhaeusler franz.steinhaeusler at utanet.at
Fri Jul 23 09:21:43 CEST 2004


On Thu, 22 Jul 2004 14:24:28 -0700, Jeff Shannon <jeff at ccvcorp.com>
wrote:

Hello Jeff,

>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).  

No. Plugin is a *function*, which receives a *drFrame object*.
It should have the purpose to "redirect" all the SetStatusText 
calls from within drFrame.

>*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 see.

>
>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.

This I want to achieve.

I betted, that there comes the question of bad design :)

>
>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...)

Thank you for your extensive explanation and for the tips.

I will think about it again.


-- 
Franz Steinhaeusler



More information about the Python-list mailing list