Python and generic programming
Kay Schluehr
kayschluehr at gmx.de
Sun Nov 21 02:19:34 CET 2004
Jive Dadson wrote:
> How about specialization? I'm relatively new to Python. I ask for
> information, not to be argumentative.
There is no such thing as template specialisation or method overloading in Python
due to the lack of static typing.
> If you have, for example, several data-types for matrices, how do you
> write code that will automatically find the right routine for quickly
> multiplying a vector by a diagonal matrix represented as a vector, and
> automatically call the right code for multiplying by a sparse matrix
> represented by some sparse coding, etc?
Here is some code that enables automatical dispatches according to a chain of
function decorators. The chain is terminated by a decorator that does not force
any type ( here symbolized by None ) and triggers a default function. The mul()
function in the example defines inner functions that represent different
algorithms on different types. The mul() function itself does not return the result
of a multiplication, but the list of "specialized" inner functions ( which are in
fact as generic as all other Python functions, but they can be regarded as
specialized in this context ).
Keep attention that the decorator chain will not work if the decorator
@when(None,"default")
is not the last one in the chain.
# decorator function
def when(types, name):
def push(f):
def eval(*t):
funcs = []
args = t[3]
conds = [t[:2]]
while 1:
s = t[2](*t[3])
if s[-1]=='stop':
conds.insert(0,s[:2])
else:
funcs = s
break
t = s
for (_types, funcname) in conds:
bTypesOk = True
if _types:
for (a, t) in zip(args, _types):
if not isinstance(a,t):
bTypesOk = False
break
if bTypesOk:
for f in funcs:
if f.func_name == funcname:
return f(*args)
else:
bTypesOk = True
raise NameError,"No available function found that matches default"
def pop(*args):
if types is None:
return eval(types,name,f,args,"stop")
return types,name,f,args,"stop"
return pop
return push
# example code
from decimal import Decimal
@when(None,"default")
@when((int,float),'mul_float')
@when((float,float),'mul_float')
@when((Decimal,Decimal),'mul_dec')
def mul(m1,m2):
def default(m1,m2):
return "default",m1*m2
def mul_float(m1,m2):
return "mul_float",Decimal(str(m1))*Decimal(str(m2))
def mul_dec(m1,m2):
return "mul_dec",m1*m2
return (default,mul_dec,mul_float)
Ciao
Kay
More information about the Python-list
mailing list