[Twisted-Python] Generic functions using PyProtocols (was Re: Components)

Phillip J. Eby pje at telecommunity.com
Fri Feb 27 21:48:44 MST 2004


At 09:58 AM 2/27/04 -0500, Phillip J. Eby wrote:
>At 12:40 AM 2/27/04 -0500, Glyph Lefkowitz wrote:
>>(BTW: a common idiom for using interfaces is to scope method names.  An
>>optimization I want to add to Twisted at some point is stateless
>>interface-method-call syntax which can do this efficiently, something
>>like: IWhatever.what(x).  I believe you should be able to avoid a bunch
>>of Python object allocation overhead by doing it that way.  Does
>>PyProtocols provide any such facility?)
>
>Not at the moment.  What I'd like to do at some point is add 
>single-dispatch generic functions, though.

Just for the heck of it, I thought I'd try whipping up a single-dispatch 
generic function using PyProtocols.  It turned out to be much easier than I 
thought; only 19 lines, in fact!

from protocols import Protocol, adapt, declareAdapter
from new import instancemethod

class GenericFunction(Protocol):

     def __init__(self, defaultFunc=None):
         Protocol.__init__(self)
         if defaultFunc is not None:
             self.add(defaultFunc,[object])

     def __call__(__self, self, *__args,**kw):
         return adapt(self,__self)(*__args,**kw)

     def add(self,func,forTypes=(),forProtocols=()):
         declareAdapter(
             lambda ob,proto: instancemethod(func,ob,type(ob)),
             provides=[self], forTypes=forTypes, forProtocols=forProtocols
         )

# Quick test/demo

def g(ob):
     print ob, "is of unknown type"

g = GenericFunction(g)


class A(object): pass
class B(A): pass
class C(A): pass

def gA(ob):
     print ob, "is an A"

g.add(gA,[A])

def gB(ob):
     print ob, "is a B"

g.add(gB,[B])


# Try it out

g(A())
g(B())
g(C())
g([])

# ====


It could probably do with some kind of 'super()'-like mechanism, but that 
would make for a rather more complex implementation, alas.  Still, it's not 
bad at all and I can think of a few places I might actually use it.  For 
example, it'd be great for writing "visitor" algorithms that need to do 
different behaviors based on the type or interfaces of the nodes.





More information about the Twisted-Python mailing list