[Python-3000] Some canonical use-cases for ABCs/Interfaces/Generics

Adam Olsen rhamph at gmail.com
Thu May 3 00:48:30 CEST 2007

On 5/1/07, Talin <talin at acm.org> wrote:
> One of my concerns in the ABC/interface discussion so far is that a lot
> of the use cases presented are "toy" examples. This makes perfect sense
> considering that you don't want to have to spend several pages
> explaining the use case. But at the same time, it means that we might be
> solving problems that aren't real, while ignoring problems that are.
> What I'd like to do is collect a set of "real-world" use cases and
> document them. The idea would be that we could refer to these use cases
> during the discussion, using a common terminology and shorthand examples.
> I'll present one very broad use case here, and I'd be interested if
> people have ideas for other use cases. The goal is to define a small
> number of broadly-defined cases that provide a broad coverage of the
> problem space.

The only use case I commonly experience is that of __init__.  For instance:

class MyClass:
    def __init__(self, x):
        if isinstance(x, basestring):
            self.stream = open(x)
            self.stream = x

It can be called with either a path or a file-like object.  It might
be possible to replace the LBYL with EAFP, passing x into open() and
catching errors, but it's not obvious what if any exception would be
raised; the try/except is too broad.

Many builtin types (int, float, etc) are conceptually similar, but
with an acceptable way to narrow down the try/except: check for an
x.__int__ method, without calling it.

It's not obvious to me how to best do this dispatching in the long
term.  If you hardcode the references to basestring then, if open()
starts accepting path objects that don't derive from str, all the
existing code will break.  Generic functions provide a cleaner way to
override them if you don't want to modify the original code, but
you'll still have to write *some* update for every piece of code that
does a check.  The only way to avoid all the updates is to create some
sort of Pathish ABC to check for, but that assumes you know you'll
switch to non-str-derived path objects when you define Pathish.

For those keeping score, that means that duck typing will *always*
fail at these problems.  You have to hardcode some way of
discriminating between types, and you'll have to rewrite all that
hardcoding if the assumptions you made no longer hold.  The goal then
is to pick assumptions that will live for the longest period of time
and require the least effort to change (and avoid making them unless
you *need* them, ie stick to duck typing if it works).

Adam Olsen, aka Rhamphoryncus

More information about the Python-3000 mailing list