[Python-3000] Adaption & generic functions [was Generic functions]
Nick Coghlan
ncoghlan at gmail.com
Wed Apr 5 11:35:03 CEST 2006
Walter Dörwald wrote:
> But if adapting is done via __call__() we have a problem: Sequence
> already provides a __call__, the constructor. Of course if this worked
>
> print Sequence([1,2,3]).len()
>
> would look much better than
>
> print Sequence.adapt([1,2,3]).len()
>
> but I'm not sure if it's possible to work around the constructor/adapt
> clash.
You can redefine __call__ in the metaclass to fix it:
Py> class ClassCall:
... class __metaclass__(type):
... def __call__(cls):
... print "Calling", cls
...
Py> ClassCall()
Calling <class '__main__.ClassCall'>
So your example would become:
class MetaInterface(type):
def __new__(mcl, name, bases, dict):
# Give each class it's own registry
cls = type.__new__(mcl, name, bases, dict)
cls.registry = {}
return cls
def register(cls, adapter, T):
cls.registry[T] = adapter
def register_for(cls, T):
# Registration decorator
def register_func(adapter):
cls.register(adapter, T)
return register_func
def __call__(cls, obj):
# Cannot construct interface instances
# Instead, calling the class triggers adaptation
for base in type(obj).__mro__:
try:
adapter = cls.registry[base]
except KeyError:
pass
if adapter is None:
return obj
return adapter(obj)
raise TypeError("can't adapt %r to %r" % (obj, cls))
class Interface(object):
__metaclass__ = MetaInterface
class Sequence(Interface):
def getitem(self, index): pass
def len(self): pass
class PythonSeqAsSequence(object): # Adapter is a normal class!
def __init__(self, obj):
self.obj = obj
def getitem(self, index):
return self.obj[i]
def len(self):
return len(self.obj)
Sequence.register(PythonSeqAsSequence, list)
print Sequence([1,2,3]).len()
# Or using the function decorator version
@Sequence.register_for(tuple)
def tuple_as_seq(obj):
class AdaptedTuple(object):
def getitem(self, index):
return obj[i]
def len(self):
return len(obj)
return AdaptedTuple()
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-3000
mailing list