On Tue, May 12, 2009 at 2:27 PM, Kent Johnson <ken...@tds.net> wrote:
> On Tue, May 12, 2009 at 8:44 AM, Jeremiah Dodds > <jeremiah.do...@gmail.com> wrote: > > On Tue, May 12, 2009 at 12:27 PM, Kent Johnson <ken...@tds.net> wrote: > > >> I don't agree with this at all. It's not at all unusual for a derived > >> class to override a base class method in order to add additional > >> functionality to it, then to call the base class method to complete > >> the implementation. __init__() is the most common example but not the > >> only one. I don't consider this a design flaw at all. Another way to > >> do this is for the base class method to call a hook method that > >> subclasses can define but IMO that is often more trouble than it is > >> worth. > >> > >> I don't see how you would use a decorator to do this. > > > > Can you give an example? > > Sure, here are real world examples from my current work project, in C#... > > Many classes define > protected override void Dispose(bool disposing) > and call > base.Dispose(disposing) > in the implementation. This is a fine example; the derived class has > to implement some extra Dispose() functionality and also must ensure > that the base class Dispose() is called. There are 55 examples of this > in my project so I would have to say it is common :-) > > GUI classes with custom painting or resizing behaviour call the base > class method to get the common behaviour, then add their particular > extra bit such as drawing a custom highlight. > > I have a class that overrides ToString() (the C# equivalent of > __str__) to provide additional output. It calls base.ToString() to get > the base class representation. > > Classes with serialization methods call the base class methods to > serialize base class fields, then serialize their own fields. > > etc... > Ahh, I stand corrected. Perhaps because the shop I work in is primarily python, and because we strongly favor composition over inheritance, I never see (python) classes being used this way. > > > I've never seen this done, outside of __init__, in > > a way where it wouldn't be clearer if the base class's methodname was > just > > named something else, and then have the Parent class's eventually > overriden > > method just call the renamed method. Put the common functionality in a > > method that's not overriden. > > Sure, you can write > > class Base(object): > def someMethod(self): > self._someMethodImpl() > > def _someMethodImpl(self): > # do something > > class Derived(Base): > def someMethod(self): > self._someMethodImpl() > # do something else > > but I don't see that that gives any advantage over the simpler > > class Base(object): > def someMethod(self): > # do something > > class Derived(Base): > def someMethod(self): > Base.someMethod(self) > # do something else > > and if you don't have control over the code for Base (perhaps it is > part of a GUI framework or other third-party code) then you don't have > a choice to use the first option. > Yes, if you don't have control over the code for Base, you don't really have a choice. Most of the time, when I see inheritance used in python, it's pretty much just classes being used as containers for common functionality. If there are two methods, one in the Base, and one in a Child, that share the same name, but not all the functionality, it will be written like so: class Base(object): def common(self): #do common stuff here def overridden(self): #do base-specific-stuff here self.common() class Child(Base): def overriden(self): #do child-specific-stuff here self.common() > > > Depending on what you need to do, you can pull out what would normally be > in > > the base classes method into a decorator that calls the subclassess > method > > and then does what it needs to do. I don't see this too often. > > Can you give an example? I still don't see how that would work or why > it would be preferable to simply calling the base class method as in > my second option above. > > Kent > Yes, but again, it's not something that I see commonly done. We have a bunch of python objects that communicate with a bunch of legacy apps via (and this is something of a simplification) HTTP. Sometimes, we need to enforce a specific delay in between POSTs or GETs for a specific app, and it turned out that there are other parts in our suite that benefit from having a delay imposed, for various reasons. Instead of putting the delay functionality into the Base class for these apps, we pulled it out into a decorator that sits in a utility module.
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor