callable virtual method

Diez B. Roggisch deets at nospam.web.de
Fri Aug 14 18:56:53 CEST 2009


Jean-Michel Pichavant schrieb:
> MRAB wrote:
>> Jean-Michel Pichavant wrote:
>>> Hi fellows,
>>>
>>> Does anyone know a way to write virtual methods (in one virtual 
>>> class) that will raise an exception only if called without being 
>>> overridden ?
>>> Currently in the virtual method I'm checking that the class of the 
>>> instance calling the method has defined that method as well.
>>>
>>> Example:
>>>
>>> class Stream(object):
>>>    """Interface of all stream objects"""
>>>    def resetStats(self):
>>>        """Reset the stream statistics. All values a zeroed except the 
>>> date."""
>>>        _log.info('Reset statistics of %s' % self)
>>>        if self.__class__.resetStats == Stream.resetStats:
>>>            raise NotImplementedError()
>>>
>>> It works but it's tedious, I have to add these 2 lines to every 
>>> virtual method, changing the content of the 2 lines.
>>>
>>> Maybe there is a nice/builtin way to do so (python 2.4)
>>>
>> Why are you checking which class it's in? The method in the base class
>> will be called only if it hasn't been overridden in the subclass.
> 
> 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.')
> 
> class GoodChild(Interface):
>    def method(self):
>       Interface.method(self) # I want to process the cool stuff done my 
> the base Interface
>       # ------------------------
>       # Specific GoodChild stuff here
>       # ------------------------
>       print 'I am a good'
>       return 'perfect'
> 
> class BadChild(Interface):
>    pass #I'm too lazy
> 
> 
> good = GoodChild()
> bad = BadChild()
> 
> good.method()
> ...hello world
> ...I am a good
> 
> bad.method()
> ...NotImplementedError: You should have read the f****** manual ! You 
> must override this method.
> 
> 
> 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.

First of all, I doubt the above code really yields that output. You are 
missing a super-call there in GoodChild

And the whole problem goes magically away if you start using OO a bit:


class Base(object):


   def method(self):
       self._do_some_work_for_method()
       print "some more work"

   def _do_some_work_for_method(self):
       raise NotImplemented


So your subclasses must implement something else instead of method - and 
voila, without any hassle things work as expected.

Diez



More information about the Python-list mailing list