"Jp Calderone" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > On Mon, 28 Mar 2005 03:57:16 GMT, Alex VanderWoude <[EMAIL PROTECTED]> wrote: > >Is there a way to override a method on a class whose source you cannot > > change in such a way that you can hook into that method's code? After doing > > some research, it appears that one way to do such a thing is to create a new > > (non-class) method, and then assign the new method to the class in question, > > thus replacing the existing class method. However, I have read vague hints > > in the documentation that this is not a good thing to do (?). Furthermore, > > you probably need access to the source code of the method you are replacing > > so that you can duplicate and modify it in your method. Now in this > > particular case that is true, but what I really want to know is whether or > > not there is an accepted Pythonic way to do this. > > > > Here's the situation. I'm using wxPython, and I want to make an enhancement > > in the __init__ method of all the frame classes. The ideal place to do this > > is in wxFrame.__init__, since any change there will automatically be > > inherited by the other frame classes (for example, wxMDIParentFrame). > > Obviously I can inherit from wxPython and make the changes in my subclass, > > but then I would have to also subclass wxMDIParentFrame and duplicate my > > enhancements there, and then use only my subclasses rather than the wx*** > > classes. > > > > Basically I want to change wxFrame.__init__ so that it looks sort of like > > this: > > > > def __init__(self, *args, **kwargs): > > # Some enhancements here. > > # The original code of this method, including the call to its > > ancestor. > > # Some more enhancements here. > > > > And then I can replace wxFrame's __init__ with my new version by assigning > > it before any frames are instantiated. > > from thirdparty.project import Something > > orig = Something.meth > def new(x, y, z): > foo() > orig(x, y, z) > bar() > Something.meth = new > > HTH, > > Jp
Well I'll be, that works: IDLE 1.0.2 >>> class FooAncestor(object): def Bar(self): print "Now in FooAncestor.Bar()" >>> class FooDescendant(FooAncestor): def Bar(self): print "Now in FooDescendant.Bar()" FooAncestor.Bar(self) print "Back in FooDescendant.Bar()" >>> OldBar = FooAncestor.Bar >>> def NewBar(self): print "Start of NewBar()" OldBar(self) print "End of NewBar()" >>> FooAncestor.Bar = NewBar >>> Foo = FooDescendant() >>> Foo <__main__.FooDescendant object at 0x00981F50> >>> Foo.Bar() Now in FooDescendant.Bar() Start of NewBar() Now in FooAncestor.Bar() End of NewBar() Back in FooDescendant.Bar() It must be because the creation of OldBar() actually instantiates a callable object using the code found in FooAncestor (which itself has not yet been instantiated). This "separates" OldBar() from the FooAncestor.Bar() definition. When an instance of FooAncestor (or one of its descendants) is created then another, different callable object is created as part of the new class (Foo in the example above). Thanks to all in this thread for your help. - Alex -- http://mail.python.org/mailman/listinfo/python-list