[Python-3000] Adaptation vs. Generic Functions
Nick Coghlan
ncoghlan at gmail.com
Wed Apr 5 16:16:34 CEST 2006
Tim Hochberg wrote:
> I like this version. The naming seems an improvement and the
> default_adapter seems like a worthy addition. I do keep wondering if
> there's some reason for a user of Protocol to call candidate_keys
> directly or it's only an implementation detail. If the there is such a
> reason, and we could figure it out, it would probably immediately
> obvious what to call it. If there isn't, perhaps it should be prefixed
> with '_' to indicate that it's not part of the public interface.
It was a toss-up, but even if it was private, it would still need to be
documented so subclasses knew how to override it. And if it's public, then it
might be a useful introspection tool on protocols. For example:
def can_adapt(protocol, *args):
for key in protocol.candidate_keys(args):
if key in protocol.registry:
return True
return False
Although, now that I think about it, mere presence in the registry doesn't
necessarily signify much - it's trivial to register an "anti-adapter" that
raises TypeError. So having this method be public may make it an attractive
nuisance, rather than something useful. . .
>> # The generic iteration example
>> @GenericFunction
>> def GenericIter(obj):
>> """This is the docstring for the generic function."""
>> # The body is the default implementation
>> if hasattr(obj, "__iter__"):
>> return obj.__iter__()
>> raise TypeError("Can't iterate over %s object" %
>> obj.__class__.__name__)
>>
>> @GenericIter.register(list)
>> def _GenericSequenceIter(obj):
>> return SequenceIter(obj)
>>
>> GenericIter.register(str)(_GenericSequenceIter)
>> GenericIter.register(unicode)(_GenericSequenceIter)
>>
>> @GenericIter.register(dict)
>> def _GenericDictIter(obj):
>> return SequenceIter(obj.keys())
>>
>
> These should all be "GenericIter.register_for", right?
I don't what happened there - I must have hit Ctrl-C instead of Ctrl-V or
something. . .
That part should have looked like:
@GenericFunction
def GenericIter(obj):
"""This is the docstring for the generic function."""
# The body is the default implementation
if hasattr(obj, "__iter__"):
return obj.__iter__()
raise TypeError("Can't iterate over %s object" % obj.__class__.__name__)
GenericIter.register(SequenceIter, list, str, unicode)
@GenericIter.register_for(dict)
def _GenericDictIter(obj):
return SequenceIter(obj.keys())
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-3000
mailing list