Python and generic programming
Glenn Andreas
gandreas at no.reply
Tue Oct 26 11:29:04 EDT 2004
In article <mailman.5295.1098427304.5135.python-list at python.org>,
Josiah Carlson <jcarlson at uci.edu> wrote:
> Roman Suzi <rnd at onego.ru> wrote:
>
> > Most Python programs are already kinda generic, yes. But generic
> > programming adds multi-sorted types control and constraints to ensure type
> > safety...
>
> "kinda generic"? That is quite the understatement.
>
> As for "type safety", Python has runtime type checking, and as a
> programmer, if you want to have varying dispatch based on type, you are
> free to do so:
>
> foo_dispatch = {(int, int):foo_int_int, #some defined function
> ...}
>
> def foo(arg1, arg2):
> foo_dispatch[(type(arg1), type(arg2))](arg1, arg2)
>
>
> With decorator syntax, the above becomes even easier.
How about something like:
class GenericFunction(object):
def _LookupSignature(cls, sig):
f = cls._GenericFunctionMap.get(sig,None)
if f: return f
# no exact match, fall back to "default"
# more complex type matching & resolution left as an excerise to
# the reader
wild = (None,) * len(sig)
f = cls._GenericFunctionMap.get(wild,None)
if f: return f
raise AttributeError(cls,str(sig))
_LookupSignature = staticmethod(_LookupSignature)
def __new__(cls, *params):
#print "new",cls,params
sig = tuple([type(x) for x in params])
return apply(GenericFunction._LookupSignature(cls,sig),params)
def DeclareTypes(function, *typelist):
import sys
c = sys._getframe(1)
cls = globals()[sys._getframe(1).f_code.co_name]
map = c.f_locals.setdefault('_GenericFunctionMap',{})
map[tuple(typelist)] = function
class SomeFunction(GenericFunction):
def IntAndList(i,l):
print "Int",i,"List",l
DeclareTypes(IntAndList,int,list)
def IntAndInt(i1,i2):
print "Int",i1,"Int",i2
DeclareTypes(IntAndInt,int,int)
def ListAndList(l1,l2):
print "List1",l1,"List2",l2
DeclareTypes(ListAndList,list,list)
def AnyAndAny(o1,o2):
print "o1",o1,"o2",o2
DeclareTypes(AnyAndAny,None,None)
def IntOnly(i):
print "Int",i
DeclareTypes(IntOnly,int)
SomeFunction(1)
SomeFunction(1,2)
SomeFunction(1,[1,2,3])
SomeFunction("Hello","World")
produces:
Int 1
Int 1 Int 2
Int 1 List [1, 2, 3]
List1 [1, 2] List2 [3, 4]
o1 Hello o2 World
(Again, with decorators, it becomes even cleaner)
More information about the Python-list
mailing list