ABCs

So Python 3000 will have abstract base classes.

As far as I know, in the Python world, an abstract base class used to mean, a base class that cannot be instantiated. Kind of like:

class Foo:
    def __init__(self):
        raise NotImplementedError, "Foo cannot be instantiated"

It would, however, be perfectly possible for an abstract base class to have valid, working methods, to be used by classes inheriting from Foo.

Apparently this isn't the case any longer. If I read PEP 3119 correctly, in Py3K-speak, an abstract base class is a way to trick isinstance() and issubclass() into believing that a given class derives from another class, when this actually isn't the case. For example:

>>> list.__bases__
(<class 'object'>,)
>>> object.__bases__
()

list derives from object, which in turn derives from nothing else. But:

>>> issubclass(list, collections.Sequence)
True

In other words, list *pretends* to derive from Sequence, but it really doesn't, and so any methods defined in Sequence will not be inherited by list.

Filtered through my old-school-Python-riddled brain, this implies the following:

  • abstract base classes mean something different now, and
  • they break isinstance and issubclass, and
  • methods defined in the ABC cannot be used by the "subclass".

Seriously, the more I read about Python 3.0, the harder it becomes for me not to be appalled. The language makes a heroic effort at fixing warts and problems and trimming fat, but at the same time it's becoming more and more complex.

I'd love to be proven wrong though. I like Python a lot, and I am (and have been) worried about what it's evolving into. But maybe Python 3.0 will actually be easy and intuitive to use, like the Python of old, and all the overly complex stuff will stay in the back rather than get in the way. I guess time will tell. (Or maybe I'm misunderstanding things... feel free to point that out. :-)

(This is mostly a matter of personal preference, of course -- for the last few years I've been gravitating toward languages with little syntax, that allow powerful new constructs to be written in the language itself. Think Scheme and Io. Python, however, has steadily been moving in the other direction.)

6 Comments »

  1. manuelg said,

    June 7, 2008 @ 12:22 am

    > It would, however, be perfectly possible for an abstract base class to have valid, working methods, to be used by classes inheriting from Foo. ... Apparently this isn't the case any longer.

    From the PEP

    > > Unlike Java's abstract methods or C++'s pure abstract methods, abstract methods as defined here may have an implementation. This implementation can be called via the super mechanism from the class that overrides it. This could be useful as an end-point for a super-call in framework using cooperative multiple-inheritance

    If something is "list" enough to be used productively as a "list" (but inheriting from "list" would just leave us with a dangling, unused empty list object), now we have a canonical way to announce to the world to treat our object as a "list", without the overhead of subjecting it to a battery of tests.

    We are all consenting adults here, so why be forced to inherit from a concrete class, just to throw away the "concrete" part. Abstract Base Classes are agreements among consenting adults.

  2. Lennart Regebro said,

    June 7, 2008 @ 12:42 am

    Well, ABC's that are not inherited from should have been called interfaces. As it is now, the ABCs in Python 3 kinda mix those concepts a bit. It may or may not be a problem, I don't know, but intuitively I would have liked a greater separation between the two. But that might be since I've used zope.interfaces for a couple of years now, and like it. :-)

  3. James said,

    June 7, 2008 @ 2:52 am

    The PEP says "The built-in list and bytes types derive from MutableSequence." MutableSequence is a subclass of Sequence. So list would derive from more than object in Py3k, which I think might remove your main objection?

    It looks to me like ABCs are just a convenient way to bundle together a series of 'promises' that a class makes about what methods it offers, like Java's interfaces. Unlike Java interfaces (and more like Ruby's modules), you can also put default implementations in the ABC, too. What seems to be the major innovation over what can be done in Python now, is that builtins will be placed under these new hierarchies.

  4. markus said,

    June 7, 2008 @ 4:05 am

    Io is definitely worth an extra look.

  5. Michael Campbell said,

    June 7, 2008 @ 7:28 am

    I anxiously await the complete reversal of how "correct" string.join(list) is when an iterable ABC gets created with .join(string) on it.

  6. Hans Nowak said,

    June 7, 2008 @ 7:40 am

    @Michael Campbell: That would indeed be great, but I doubt that it's ever going to happen, considering how vehemently the dev team defends str.join... But that would be a topic for another blog post. :-)

RSS feed for comments on this post

Leave a Comment