Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

callable virtual method

0 views
Skip to first unread message

Jean-Michel Pichavant

unread,
Aug 14, 2009, 10:49:47 AM8/14/09
to Python List
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)

JM

MRAB

unread,
Aug 14, 2009, 11:49:52 AM8/14/09
to Python List
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.

Diez B. Roggisch

unread,
Aug 14, 2009, 11:50:47 AM8/14/09
to
Jean-Michel Pichavant schrieb:

Python has no concept of "virtual" methods. A simple


class Stream(object):


def resetStats(self):
raise NotImplemented


is all you need. Once a subclass overrides resetStats, that
implementatino is used.

Additionally, there are modules such as zope.interface out there, that
let you define more formally what an interface is, and declare who's
implementing it. I don't used this myself though, so I can't really
comment to which extend it e.g. warns you if you subclass *without*
implementing.

Diez

Steven D'Aprano

unread,
Aug 14, 2009, 11:56:27 AM8/14/09
to
On Fri, 14 Aug 2009 16:49:47 +0200, 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.

I'm not entirely sure of the terminology -- is this the same as an
abstract base class? Googling has not enlightened me. Given your example,
it seems to be.


> 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()

The usual idiom I've seen for abstract methods is to simplify the check,
and to put it *before* any work is done:

class Stream(object):
"""Interface of all stream objects"""
def resetStats(self):

if self.__class__ is Stream:
raise NotImplementedError()


_log.info('Reset statistics of %s' % self)

Even simpler is to just put the check in __init__, so to prevent the
caller from creating an instance of the class:

class AbstractStream(object):
def __init__(self):
if self.__class__ is Stream:
raise NotImplementedError('abstract class')
def resetStats(self):
# This does not need to be over-ridden.


_log.info('Reset statistics of %s' % self)

def whatever(self):
# This *must* be over-ridden, and *cannot* be called
raise NotImplementedError('abstract method')


If you have a lot of methods, you can probably reduce the boilerplate
with decorators:


# Untested
from functools import wraps
def abstract(func):
# Abstract methods don't have to be over-ridden, so long as they
# are called from a subclass of the abstract class.
@functools.wraps(func)
def inner(self, *args, **kwargs):
if self.__class__ is Stream:
raise NotImplementedError()
return func(self, *args, **kwargs)
return inner

def virtual(func):
# Virtual methods must be over-ridden, and must not be called by
# inheritance.
@functools.wraps(func)
def inner(self, *args, **kwargs):
raise NotImplementedError()
return inner

class Stream(object):
@abstract
def __init__(self):
pass
def resetStats(self):


_log.info('Reset statistics of %s' % self)

@virtual
def whatever(self):
pass

--
Steven

Jean-Michel Pichavant

unread,
Aug 14, 2009, 12:49:26 PM8/14/09
to Python List
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.

JM

Diez B. Roggisch

unread,
Aug 14, 2009, 12:56:53 PM8/14/09
to
Jean-Michel Pichavant schrieb:

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

Jean-Michel Pichavant

unread,
Aug 14, 2009, 1:43:15 PM8/14/09
to pytho...@python.org

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


Nigel Rantor

unread,
Aug 14, 2009, 1:53:02 PM8/14/09
to Jean-Michel Pichavant, pytho...@python.org
Jean-Michel Pichavant wrote:
>
> 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.

I suggest you reconsider.

You asked a question and have been given a standard way of achieving the
desired outcome.

It's common in OO to use a Template pattern like this.

If you're not interested in finding out how loads of people have already
solved the problem then why ask?

The methods that require overriding can be prefixed with an underscore
so that people get a hint that they are an implementation detail rather
than part of the public interface.

I don't see your problem, other than a vague aesthetic unease.

Regards,

n

Steven D'Aprano

unread,
Aug 14, 2009, 2:20:41 PM8/14/09
to
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

Jean-Michel Pichavant

unread,
Aug 14, 2009, 2:29:03 PM8/14/09
to pytho...@python.org
I understand how refuting some obvious solution may look just stupid.
You're right, I shouldn't have asked.

By the way I'd like to know if I am I alone to find that

class Stream:
def start
def stop
def reset

is better than

class Stream:
def start
def _start
def stop
def _stop
def reset
def _reset

(try to figure out with 20+ methods)
What you call aesthetic may sometimes fall into readability.


JM

Nigel Rantor

unread,
Aug 14, 2009, 2:53:37 PM8/14/09
to Jean-Michel Pichavant, pytho...@python.org
Jean-Michel Pichavant wrote:
> Nigel Rantor wrote:
>> Jean-Michel Pichavant wrote:
>>>
>>> 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.
>>
>> I suggest you reconsider.
>>
>> You asked a question and have been given a standard way of achieving
>> the desired outcome.
>>
>> It's common in OO to use a Template pattern like this.
>>
>> If you're not interested in finding out how loads of people have
>> already solved the problem then why ask?
>>
>> The methods that require overriding can be prefixed with an underscore
>> so that people get a hint that they are an implementation detail
>> rather than part of the public interface.
>>
>> I don't see your problem, other than a vague aesthetic unease.
>>
>> Regards,
>>
>> n
> I understand how refuting some obvious solution may look just stupid.
> You're right, I shouldn't have asked.

I never said it seemed stupid. I was merely curious as to why you'd ask
a question and ignore solutions.

> By the way I'd like to know if I am I alone to find that
>
> class Stream:
> def start
> def stop
> def reset
>
> is better than
>
> class Stream:
> def start
> def _start
> def stop
> def _stop
> def reset
> def _reset
>
> (try to figure out with 20+ methods)
> What you call aesthetic may sometimes fall into readability.

Depends on what you mean by "better".

Do you mean pleasing to your eye or performs the task you want it to?

Assuming you are taking the aesthetic viewpoint I think that in this
case it will depend on how you set out your code.

Realise that all of the underscore methods for your class are
boilerplate, they simply raise an exception.

They can all be at the end of the file, commented as an entire block to
be left alone.

Editing the main body of code is then fairly easy, and uncluttered...

e.g.

#
# Stream class blah blah blah
#
class Stream:

def start

def stop

def reset

#
# stubs to be over-ridden in sub-classes, add one for each
# method that requires overriding.
#
def _start
def _stop
def _reset

Regards,

Nigel

p.s. Please take this in the spirit it is offered. I'm trying to stop
you from ignoring a good suggestion, not make you feel like a fool.

Dave Angel

unread,
Aug 14, 2009, 3:24:39 PM8/14/09
to Jean-Michel Pichavant, pytho...@python.org
Jean-Michel Pichavant wrote:
> <div class="moz-text-flowed" style="font-family: -moz-fixed">Nigel
> Rantor wrote:
>> Jean-Michel Pichavant wrote:
>>>
>>> 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.
>>
>> I suggest you reconsider.
>>
>> You asked a question and have been given a standard way of achieving
>> the desired outcome.
>>
>> It's common in OO to use a Template pattern like this.
>>
>> If you're not interested in finding out how loads of people have
>> already solved the problem then why ask?
>>
>> The methods that require overriding can be prefixed with an
>> underscore so that people get a hint that they are an implementation
>> detail rather than part of the public interface.
>>
>> I don't see your problem, other than a vague aesthetic unease.
>>
>> Regards,
>>
>> n
> I understand how refuting some obvious solution may look just stupid.
> You're right, I shouldn't have asked.
>
> By the way I'd like to know if I am I alone to find that
>
> class Stream:
> def start
> def stop
> def reset
>
> is better than
>
> class Stream:
> def start
> def _start
> def stop
> def _stop
> def reset
> def _reset
>
> (try to figure out with 20+ methods)
> What you call aesthetic may sometimes fall into readability.
>
>
> JM
>
>
> </div>
>
Usually when one defines an abstract base class, one expects many people
will derive from it, as opposed to only one having to write it. So if
the base must be "ugly" according to some definition, so be it.
Aesthetics are quite subjective.

Nigel's approach has another benefit not stated, which is to keep the
child class code simpler. They avoid the need to call any base class
method to access the common logic. The downside is it assumes that the
common logic will always be either at the beginning or always at the end
of the child classes implementation. That's because the base class has
hardcoded where in its implementation to call the child class method.

Anyway, without arguing for or against either approach, I'd point out
that you could have an extra formal parameter in the base method, which
is a private signal from the child class that this is the internal
call. Missing such a formal parameter would then trigger the "missing
method in derived class" error message. You'd check such a parameter
the same place as you're now checking the object's type.

DaveA


Jean-Michel Pichavant

unread,
Aug 14, 2009, 4:22:10 PM8/14/09
to Steven D'Aprano, pytho...@python.org
Sometimes the base is doing cool stuff but incomplete stuff which
requires knowledge only hold by the sub class. In my case the interface
is a high level interface for a software that can run on multiple
hardware platforms. Only the sub class has knowledge on how to operate
the hardware, but no matter the hardware it still produces the same effect.

Let's say I have 50 different hardwares, I'll have 50 sub classes of
Interface with the 'start' method to define. It wouldn't be appropriate
(OO programming)to write 50 times '_log.debug('Starting %s' % self)' in
each child start method when the simple task of logging the call can be
nicely handled by the base class.

In the meantime, I must make sure the user, who is not a python guru in
this case, has implemented the start method for his hardware, because
only him knows how to effectively start this hardware. I don't want him
to come to me saying, "I got no error, still my hardware does not
start". You can then blame him for not reading the docs, but it will
still be less expensive to throw a nice exception with an accurate feedback.

[snip]


> class VerboseGoodChild(Interface):
> # forced to over-ride methods for no good reason
>

Definitely no !! This is the purpose of an interface class: to force
people to write these methods. They *are* required, if they were not,
they would not belong to the Interface.

JM

Jean-Michel Pichavant

unread,
Aug 14, 2009, 5:00:01 PM8/14/09
to Dave Angel, pytho...@python.org
I think this is a severe issue.
You prevent the sub class from writing
def foo(self):
pre()
Base.foo(self)
post()

> Anyway, without arguing for or against either approach, I'd point out
> that you could have an extra formal parameter in the base method,
> which is a private signal from the child class that this is the
> internal call. Missing such a formal parameter would then trigger the
> "missing method in derived class" error message. You'd check such a
> parameter the same place as you're now checking the object's type.
>
> DaveA
>
>


talking about approaches:

1/
class Interface:
def foo(self):
if self.__class__.foo == Interface.foo:
raise NotImplementedError

2/
class Interface:
def foo(self):
self._foo()

def _foo(sef):
raise NotImplementedError

Are they so different ? They both require about the same amount of extra
characters, they're both readable. The second is a very classic OO
layout, the first is more flexible for the sub classes and spare some
method definition.

This thread may live again, I cannot say but I'd like to thanks all who
gave me their valuable idea on the subject, I mean it. Please don't take
my skepticism as a lack of consideration.

JM


Christian Heimes

unread,
Aug 14, 2009, 6:25:00 PM8/14/09
to pytho...@python.org
Jean-Michel Pichavant wrote:
> talking about approaches:
>
> 1/
> class Interface:
> def foo(self):
> if self.__class__.foo == Interface.foo:
> raise NotImplementedError
>
> 2/
> class Interface:
> def foo(self):
> self._foo()
>
> def _foo(sef):
> raise NotImplementedError

Please don't call it an interface when it's really an abstract base
class. And abstract base classes are probably the solution the OP is
looking for, http://docs.python.org/library/abc.html

Christian

Scott David Daniels

unread,
Aug 15, 2009, 12:11:49 PM8/15/09
to

But there _is_ one moment when you can check those things, then avoid
checking thereafter: object creation. So you can complicate your
__init__ (or __new__) with those checks that make sure you instantiate
only fully defined subclasses:

# obviously not tested except in concept:

class Base(object_or_whatever):
def __init__(self, ...):
class_ = self.__class__
if class_ is Base:
raise TypeError('Attempt to instantiate Base class')
for name in 'one two three four':
if getattr(Base, name) is not getattr(Base, name):
raise NotImplementedError(
'%s implementation missing' % name)
...

--Scott David Daniels
Scott....@Acm.Org

Jean-Michel Pichavant

unread,
Aug 16, 2009, 9:59:18 AM8/16/09
to Scott David Daniels, pytho...@python.org
That could do the trick, sparing me from writing additional code in each
methods. Thanks.

JM

Christian Heimes

unread,
Aug 16, 2009, 10:07:13 AM8/16/09
to Jean-Michel Pichavant, pytho...@python.org, Scott David Daniels
Jean-Michel Pichavant wrote:
>> Scott....@Acm.Org
> That could do the trick, sparing me from writing additional code in each
> methods. Thanks.

Why are you trying to reinvent the wheel? Python's abc module already
takes care of these details.

Christian

Jean-Michel Pichavant

unread,
Aug 16, 2009, 10:13:46 AM8/16/09
to Christian Heimes, pytho...@python.org
Sadly I'm working with python 2.4. Anyway it's good to hear they've
added ABC support to python, didn't know that. I didn't know there was a
difference between interface and abstract classes as well. With a little
bit of googling, I found out that actually Interface classes do not
provide any implementation.
What I'm looking for is definitely an abstract class.

JM

jean-michel Pichavant

unread,
Aug 16, 2009, 10:17:39 AM8/16/09
to Christian Heimes, pytho...@python.org, Scott David Daniels
Christian Heimes a �crit :
I'm working with python 2.4 and don't plan to change. The abc module
would have been exactly what I was looking for. I'll keep it mind if I
ever upgrade to python 2.6+

JM

Bruno Desthuilliers

unread,
Aug 17, 2009, 8:33:22 AM8/17/09
to
Jean-Michel Pichavant a �crit :
(snip)

> Sometimes the base is doing cool stuff but incomplete stuff which
> requires knowledge only hold by the sub class. In my case the interface
> is a high level interface for a software that can run on multiple
> hardware platforms. Only the sub class has knowledge on how to operate
> the hardware, but no matter the hardware it still produces the same effect.
>
> Let's say I have 50 different hardwares, I'll have 50 sub classes of
> Interface with the 'start' method to define. It wouldn't be appropriate
> (OO programming)to write 50 times '_log.debug('Starting %s' % self)' in
> each child start method when the simple task of logging the call can be
> nicely handled by the base class.

Which is exactly one of the use cases for the Template Method pattern in
traditional OO design.

For the record, Python can offer other solutions to this kind of problem
- like a combination of decorators and metaclasses.

> In the meantime, I must make sure the user, who is not a python guru in
> this case, has implemented the start method for his hardware,

whether he has to implement the 'start' or '_start' method doesn't make
any difference here.

Bruno Desthuilliers

unread,
Aug 17, 2009, 8:35:19 AM8/17/09
to
Jean-Michel Pichavant a �crit :
> Scott David Daniels wrote:
(snip)

>> But there _is_ one moment when you can check those things, then avoid
>> checking thereafter: object creation. So you can complicate your
>> __init__ (or __new__) with those checks that make sure you instantiate
>> only fully defined subclasses:

That's something I'd rather do in a custom metaclass. But YMMV, of course...

0 new messages