473,386 Members | 1,793 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Abstract Base Classes

Howdy all,

Okay, so Guido doesn't like Abstract Base Classes[0], and interfaces
are the way of the future[1]. But they're not here now, and I
understand ABCs better.

I want my modules to (sometimes) define an abstract base exception
class, that all other exceptions in that module inherit from.

class FooException(Exception):
""" Base class for all FooModule exceptions """

class FooBadFilename(FooException):
""" Raised when a bad filename is used in a foo """

class FooUnknownBar(FooException, KeyError):
""" Raised when an unknown bar is used with a foo """

However, there should never be an exception raised of class
FooException, and in fact I want that to cause an appropriate error to
be raised from the module.

Normally, I'd pick some key part of the functionality of the class,
and cause that to raise NotImplementedError. It's then the
responsibility of subclasses to override that.

However, in the case of exceptions, I don't want to override *any*
functionality; everything should be provided by the base classes. It'd
be messy to have to override something in every subclass just to
ensure the abstraction of the module base exception.

I've tried doing this in the __init__():

class FooException(Exception):
""" Base class for all FooModule exceptions """
def __init__(self):
raise NotImplementedError, \
"%s is an abstract class for exceptions" % self.__class__

When I use this, I discovered to my horror that the subclasses were
calling FooException.__init__ -- which I though wasn't supposed to
happen in Python!

It's also rather semantically weird, to my eye.

Can I do something tricky with checking base classes in the
FooException.__init__() ?
[0] Although he's apparently been quoted earlier as saying he did.
He's changed his mind[1] since then.

[1] <URL:http://www.artima.com/weblogs/viewpost.jsp?thread=92662>

--
\ "The shortest distance between two points is under |
`\ construction." -- Noelie Alito |
_o__) |
Ben Finney
Nov 11 '05 #1
6 1823
Ben Finney <bi****************@benfinney.id.au> writes:
I've tried doing this in the __init__():

class FooException(Exception):
""" Base class for all FooModule exceptions """
def __init__(self):
raise NotImplementedError, \
"%s is an abstract class for exceptions" % self.__class__

When I use this, I discovered to my horror that the subclasses were
calling FooException.__init__ -- which I though wasn't supposed to
happen in Python!
It's also rather semantically weird, to my eye.
Calling __init__ is handled just like any other method (this is a good
thing), so if your subclasses fail to define __init__, the version in
the superclass gets called. If it were otherwise, every class would
have to declare __init__ just to call super(cls, self).__init__.
Can I do something tricky with checking base classes in the
FooException.__init__() ?


Untested:

class FooException(Exception):
def __init__(self):
if self.__class__ == FooException:
raise NotImplementedError,
"FooException is an abstract class for exceptions"

Personally, I find this unpythonic. FooException doesn't contribute
anything, and has no real reason for existing. If Python did static
type checking, it would make sense, but python doesn't, so it doesn't.

If you hadn't referenced interfaces, I'd suspect you might be planing
on catching all FooExceptions in a try:/except:. I'm not sure you'll
be able to list an interace in an except clause when they come to
exist, though.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Nov 11 '05 #2
Mike Meyer <mw*@mired.org> wrote:
class FooException(Exception):
def __init__(self):
if self.__class__ == FooException:
raise NotImplementedError,
"FooException is an abstract class for exceptions"
Shall try this when I get the chance. Thanks.
Personally, I find this unpythonic. FooException doesn't contribute
anything, and has no real reason for existing.


The purpose is to be able to specify an 'except FooException:' in some
user of that module; this allows exceptions from that particular
module to be handled differently, if necessary. (And so on for a
hierarchy of modules in a package, if that's warranted.)

--
\ "A cynic is a man who knows the price of everything and the |
`\ value of nothing." -- Oscar Wilde |
_o__) |
Ben Finney
Nov 11 '05 #3
Ben Finney wrote:
Howdy all,

Okay, so Guido doesn't like Abstract Base Classes[0], and interfaces
are the way of the future[1]. But they're not here now, and I
understand ABCs better. This is a very interesting discussion - not all of it understandable to me.

Are interfaces really in our future?

I found the contributions of "steffen" particularly appealing.
Interfaces seem to add another level of complexity without significant
benefit.

Colin W.
I want my modules to (sometimes) define an abstract base exception
class, that all other exceptions in that module inherit from.

class FooException(Exception):
""" Base class for all FooModule exceptions """

class FooBadFilename(FooException):
""" Raised when a bad filename is used in a foo """

class FooUnknownBar(FooException, KeyError):
""" Raised when an unknown bar is used with a foo """

However, there should never be an exception raised of class
FooException, and in fact I want that to cause an appropriate error to
be raised from the module.

Normally, I'd pick some key part of the functionality of the class,
and cause that to raise NotImplementedError. It's then the
responsibility of subclasses to override that.

However, in the case of exceptions, I don't want to override *any*
functionality; everything should be provided by the base classes. It'd
be messy to have to override something in every subclass just to
ensure the abstraction of the module base exception.

I've tried doing this in the __init__():

class FooException(Exception):
""" Base class for all FooModule exceptions """
def __init__(self):
raise NotImplementedError, \
"%s is an abstract class for exceptions" % self.__class__

When I use this, I discovered to my horror that the subclasses were
calling FooException.__init__ -- which I though wasn't supposed to
happen in Python!

It's also rather semantically weird, to my eye.

Can I do something tricky with checking base classes in the
FooException.__init__() ?
[0] Although he's apparently been quoted earlier as saying he did.
He's changed his mind[1] since then.

[1] <URL:http://www.artima.com/weblogs/viewpost.jsp?thread=92662>

Nov 11 '05 #4
Ben Finney <bi****************@benfinney.id.au> wrote:
I want my modules to (sometimes) define an abstract base exception
class, that all other exceptions in that module inherit from.


Not a whole lot of feedback on this, so here's the implementation I
decided upon.

class FooException(Exception):
""" Base class for all exceptions in this module """
def __init__(self):
if self.__class__ is EnumException:
raise NotImplementedError, \
"%s is an abstract class for subclassing" % self.__class__

class FooBarTypeError(TypeError, FooException):
""" Raised when the foo gets a bad bar """

class FooDontDoThatError(AssertionError, FooException):
""" Raised when the foo is asked to do the wrong thing """
This allows the exceptions for the module to behave similarly to their
leftmost base exception; but because they all inherit from the
abstract base class exception for the module, it also allows for this
idiom:

import foo

try:
foo.do_stuff(bar)
except FooException, e:
special_error_handler(e)
Any more comment on this technique? Any other significant use cases
for abstract base classes?

--
\ "For man, as for flower and beast and bird, the supreme triumph |
`\ is to be most vividly, most perfectly alive" -- D.H. Lawrence. |
_o__) |
Ben Finney
Nov 22 '05 #5
Ben Finney <bi****************@benfinney.id.au> wrote:
I want my modules to (sometimes) define an abstract base exception
class, that all other exceptions in that module inherit from.


[re-posting with the implementation properly foo-ified]

Not a whole lot of feedback on this, so here's the implementation I
decided upon.

class FooException(Exception):
""" Base class for all exceptions in this module """
def __init__(self):
if self.__class__ is FooException:
raise NotImplementedError, \
"%s is an abstract class for subclassing" % self.__class__

class FooBarTypeError(TypeError, FooException):
""" Raised when the foo gets a bad bar """

class FooDontDoThatError(AssertionError, FooException):
""" Raised when the foo is asked to do the wrong thing """
This allows the exceptions for the module to behave similarly to their
leftmost base exception; but because they all inherit from the
abstract base class exception for the module, it also allows for this
idiom:

import foo

try:
foo.do_stuff(bar)
except FooException, e:
special_error_handler(e)
Any more comment on this technique? Any other significant use cases
for abstract base classes?

--
\ "For man, as for flower and beast and bird, the supreme triumph |
`\ is to be most vividly, most perfectly alive" -- D.H. Lawrence. |
_o__) |
Ben Finney
Nov 22 '05 #6
Ben Finney wrote:
Ben Finney <bi****************@benfinney.id.au> wrote:
I want my modules to (sometimes) define an abstract base exception
class, that all other exceptions in that module inherit from.

[re-posting with the implementation properly foo-ified]


Isn't the proper Python idiom to use Monty Python
concepts, e.g. spam, vikings, parrots, after dinner
mints (wafer thin or otherwise), gumby, etc.?

As well as being Pythonic, it annoys the Lisp, Perl and
C developers even more than ... sarcasm.

*wink*
Not a whole lot of feedback on this, so here's the implementation I
decided upon.


[snip]

Seems good to me.
--
Steven.

Nov 22 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Dave Veeneman | last post by:
Is is legal to declare abstract members in non-abstract classes? How about non-abstract members in abstract classes? I am writing a base class with three derived classes. The base class will...
4
by: Chuck Bowling | last post by:
I am using CodeDOM to generate source files. The classes being generated have a const string member. This member is referenced in an abstract base class but declared in the inheriting class. I...
18
by: Bradley | last post by:
I'm trying to determine if there's a general rule for when an Interface should used vs. an Abstract Class. Is there any design advantage to using one or the other? Brad
9
by: Sean Kirkpatrick | last post by:
To my eye, there doesn't seem to be a whole lot of difference between the two of them from a functional point of view. Can someone give me a good explanation of why one vs the other? Sean
7
by: jason | last post by:
In the microsoft starter kit Time Tracker application, the data access layer code consist of three cs files. DataAccessHelper.cs DataAcess.cs SQLDataAccessLayer.cs DataAcccessHelper appears...
2
by: talkingpidgin | last post by:
I am trying to figure out why it is not conventional to use protected constructors in abstract classes since the only time they should be called is by the constructors of it's derived classes. Is...
0
by: emin.shopper | last post by:
I had a need recently to check if my subclasses properly implemented the desired interface and wished that I could use something like an abstract base class in python. After reading up on metaclass...
2
by: Zytan | last post by:
I know that WebRequest.GetResponse can throw WebException from internet tutorials. However in the MSDN docs: http://msdn2.microsoft.com/en-us/library/system.net.webrequest.getresponse.aspx It...
4
by: David Zha0 | last post by:
Hi, "when we call a virtual method, the runtime will check the instance who called the method and then choose the suitable override method, this may causes the performance drop down", is this...
5
by: =?Utf-8?B?UmljaA==?= | last post by:
Greetings, I am actually a VB.Net guy, but I have worked somewhat with C++ and C#. I just want to ask about the relationship between Abstract Classes and Interfaces. My first question is if...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.