Newbie Question: Abstract Class in Python (fwd)

Lulu of the Lotus-Eaters mertz at gnosis.cx
Mon Jul 7 01:56:08 EDT 2003


|Kevin Bass <kbass1 at nc.rr.com> wrote:
|>I am new to Python and want to know how to implement an abstract
|>class? I have read through different books and I have no found this
|>information.  Thanks!

aahz at pythoncraft.com (Aahz) wrote previously:
|Simple answer: you don't.  Python doesn't really have that concept.  If
|you tell us what you're trying to do, we can explain how to do that in
|Python.

While I agree with some of the warnings against using an abstract class
unnecessarily, it *is* both possible and straightforward to do so in
Python.

Here's the right part of the warnings.  Python isn't based around the
idea of not trusting later programmers like some bondage-and-discipline
languages are.  There is no need to prohibit users from using your class
how they think best.  Languages like C++ and Java go overboard with
their concepts of encapsulation.

Here's the wrong part.  An abstract parent might very well be able to
provide implementations of many useful methods, but in principle not
want to program some essential support method.  The very reasonable idea
is that there can be several different ways for children to implement
the missing functionality... some implelentation is required, but the
parent doesn't want to pre-judge which one children should choose.

At bare minimum, here's how to implement an abstract class:

    class Abstract:
        def __init__(self):
            raise NotImplementedError, "Must subclass me"

A non-abstract child will need to implement its own __init__() to become
concrete.

But a better approach is usually to have an abstract parent be specific
about what it needs:

    >>> class SpecificAbstract:
    ...     def __init__(self):
    ...         if not hasattr(self,'support_meth'):
    ...             raise NotImplementedError, "Must provide .support_meth()"
    ...     def some_method(self):
    ...         foo = self.support_meth()
    ...         #...more with foo...
    ...
    >>> o = SpecificAbstract()
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 4, in __init__
    NotImplementedError: Must provide .support_meth()
    >>> class InadequateChild(SpecificAbstract):
    ...     def other_method(self):
    ...         "...do something..."
    >>> o = InadequateChild()
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 4, in __init__
    NotImplementedError: Must provide .support_meth()
    >>> class SpecificConcrete(SpecificAbstract):
    ...     def support_meth(self):
    ...         return "Something"
    ...
    >>> o = SpecificConcrete()
    >>> # happy

At times it is also useful to only have certain non-magic methods raise
NotImplementedError.  The missing functionality might not be needed for
every instance, but you let users know that it is as early as possible.

Yours, Lulu...

--
 mertz@   _/_/_/_/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY:_/_/_/_/ v i
gnosis  _/_/                    Postmodern Enterprises         _/_/  s r
.cx    _/_/  MAKERS OF CHAOS....                              _/_/   i u
      _/_/_/_/_/ LOOK FOR IT IN A NEIGHBORHOOD NEAR YOU_/_/_/_/_/    g s






More information about the Python-list mailing list