[Python-3000] Adaptation vs. Generic Functions

Guido van Rossum guido at python.org
Wed Apr 5 06:10:30 CEST 2006


On 4/4/06, Alex Martelli <aleaxit at gmail.com> wrote:
>
> On Apr 4, 2006, at 5:29 PM, Guido van Rossum wrote:
>     [excellent example, mostly snipped]
>
> Just for when this will be published/blogged (as it deserves to be!),
> tiny nit:
>
> >     if hasattr(obj, "__iter__"):
> >         return obj.__iter__()
> >     raise TypeError("Can't iterate over a %s object" %
> > obj.__class__.__name__)
>
> I think we should check/get __iter__ from obj.__class__, not from obj
> itself (new style classes only take special methods from the type,
> not from the instance). This applies to other occurrences of this
> pattern later, too.

I prefer to ignore that detail when writing Python code though.

> >     def register(self, T, A):
> >         self.registry[T] = A
>
> Why not accept more than one type (for the same adapter) at one gulp?
>
>    def register(self, A, *Ts):
>      for T in Ts:
>        self.registry[T] = A

I had that first. :-) Deleted it because it just distracted.

> >     def __call__(self, T):
> >         # This is invoked when a Protocol instance is used as a
> > decorator.
> >         def helper(A):
> >             self.register(T, A)
> >             return A
> >         return helper
>
> And similarly here, take *Ts in the __call__ and pass it on to
> self.register.

Ditto.

> > @AdaptingIterProtocol(list)
> > def _AdaptingSequenceIter(obj):
> >     return SequenceIter(obj)
> >
> > AdaptingIterProtocol.register(str, _AdaptingSequenceIter)
> > AdaptingIterProtocol.register(unicode, _AdaptingSequenceIter)
>
> So this could become
>
> AdaptingIterProtocol.register(SequenceIter, list, str, unicode)

Which I wrote at some point. :-)

> ((no real need for the extra layer represented by
> _AdaptingSequenceIter, though you could use it, if you insisted, with
> all the types at one gulp.
>
> > def AdaptingIter(obj):
> >     return AdaptingIterProtocol.adapt(obj)
>
> Similarly, in the name of cutting down useless layers,
>
> AdaptingIter = AdaptingIterProtocol.adapt
>
> seems preferable to me.

Right.

In another post, Tim Hochberg uses __call__ instead of adapt; then we
could just rename AdaptingIterProtocol to AdaptingIter and cut down
one more layer. (Of course this presumes one doesn't have any *other*
use in mind for calling a protocol -- which may not work for some
frameworks.)

> There seems to be an asymmetry in the functionality of adaptation and
> generics as presented: adaptation as presented supports a search on
> the mro but for one argument only, generics support N arguments but
> no mro search.  To enable closer comparison, we might have generics
> support 1 argument and mro search, too, just as to ensure the feature
> set is identical (they both can be extended, with different degree of
> difficulty no doubt, but 1 argument each, with or w/o mro search,
> seems to allow more direct comparison).

Right. But I didn't have the time to do that, and I wanted the
examples to be so short that more people could potentially understand
them by just reading them top-to-buttom.

--
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list