callable virtual method

Jean-Michel Pichavant jeanmichel at sequans.com
Fri Aug 14 19:43:15 CEST 2009


Diez B. Roggisch wrote:
> 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

It does yield that output, there's an unbound call to Interface.method.

Your solution will work, for sure. The problem is that it will dumb down 
the Base class interface, multiplying the number of methods by 2. This 
would not be an issue in many cases, in mine there's already too much 
meaningful methods in my class for me to add artificial ones.

Thanks for the tip anyway.
JM









More information about the Python-list mailing list