class A: pass
class B: pass
a1 = A(); a2 = A()
b1 = B(); b2 = B()
ofunc = Overload()
ofunc.register( lambda x,a: 'float x A', sig(1.,a2) )
ofunc.register( lambda x, b: 'float x B', sig(1.,b2) )
ofunc.register( lambda i: '{int, long}', [sig(1), sig(1L)] )
ofunc.register( lambda a,b: 'A x B', sig(a1,b1) )
ofunc.register( lambda b,a: 'B x A', sig(b1,a1) )
ofunc.register( lambda ab1,ab2: '{A x A, B x B}', [sig(a1,a1), sig(b2,b1)] )
ofunc.register( lambda: 'void', [()] )
# if a __call__ special method is introduced, these could be
# print ofunc(1)
# etc
print ofunc.call(1)
print ofunc.call(a1, b2)
print ofunc.call(a2, a2)
print ofunc.call(b2, a2)
print ofunc.call(32L * 54)
print ofunc.call(1.0, b1)
print ofunc.call()
print ofunc.call(1L, b1)
prints this:
{int, long}
A x B
{A x A, B x B}
B x A
{int, long}
float x B
void
Traceback (innermost last):
...
TypeError: unregistered signature (<type 'long int'>, <class B at 657b8>)
By modifying an executable prototype, it's possible to formulate proposed
rules precisely and give 'em a test run.
observingly y'rs - tim
Tim Peters tim@ksr.com
not speaking for Kendall Square Research Corp
class C: pass
_it = type(C())
del C
def _type(x):
t = type(x)
if t is _it: t = x.__class__
return t
def sig( *values ):
return list2tuple( map(_type, values) )
def list2tuple(list):
tup = ()
for x in list: tup = tup + (x,)
return tup
class Overload:
def __init__(self):
self.sig2func = {}
def register(self, func, sig_or_sig_list):
if type(sig_or_sig_list) == type(()):
sig_or_sig_list = [sig_or_sig_list]
for sig in sig_or_sig_list:
self.sig2func[sig] = func
def call(self, *args):
signature = apply(sig, args)
try:
func = self.sig2func[signature]
except KeyError:
raise TypeError, 'unregistered signature ' + `signature`
return apply(func, args)
# end of module