callable virtual method

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Aug 14 14:20:41 EDT 2009


On Fri, 14 Aug 2009 18:49:26 +0200, Jean-Michel Pichavant wrote:

> Sorry guys (means guys *and* gals :op ), I realized I've not been able
> to describe precisely what I want to do. I'd like the base class to be
> virtual (aka abstract). However it may be abstract but it does not mean
> it cannot do some usefull stuff.
> 
> 
> Here is the schema of my abstract methods :
> 
> class Interface(object):
>     def method(self):
>         # ---------------------
>         # some common stuff executed here
>         # ---------------------
>         print 'hello world'
>         # ---------------------
>         # here shall stand child specific stuff (empty in the interface
> method)
>         # ---------------------
>         if self.__class__.method == Interface.method:
>             raise NotImplementedError('You should have read the f******
> manual ! You must override this method.')


Okay, so I want to sub-class your Interface class. As you said, the 
methods in the abstract class are still useful, so in my class, I don't 
need any extra functionality for some methods -- I'm happy with just the 
"common stuff". So I use normal OO techniques and over-ride just the 
methods I need to over-ride:

class GoodChild(Interface):
    # no need to over-ride method, because it does everything I want
    # but over-ride other methods that don't
    def whatever(self):
        print "Whatever..."
        return Interface.whatever()

But now my class fails, with an insulting error message *wink*, and you 
force me to write a whole lot of crappy stupid boilerplate code:

class VerboseGoodChild(Interface):
    # forced to over-ride methods for no good reason
    def method(self):
        return Interface.method(self)
    def another_method(self):
        return Interface.another_method(self)
    def yet_another_method(self):
        return Interface.yet_another_method(self)
    def still_more_methods(self):
        return Interface.still_more_methods(self)
    # Whew! That was a waste of effort. Now at last over-ride the
    # methods I need to:
    def whatever(self):
        print "Whatever..."
        return Interface.whatever()

After the fourth such class, I say "Bugger this for a game of soldiers" 
and dump your Interface class for something else.


> The reason I'd like to do so: I'll be providing the Interface, but child
> classes will be overridden by others. Having a reliable error RTFM
> feedback is a time saver, for me and the users. I hope I clarified my
> issue.

The usual way of implementing abstract base classes is to simply prohibit 
instantiation of the class, but allow all other inheritance. Putting 
useful functionality in methods, but then prohibiting subclasses from 
using them without jumping through hoops first, seems rather perverse to 
me.



-- 
Steven



More information about the Python-list mailing list