Zope3 and Generic Functions
Paul Wilson <[email protected]>
| Newsgroups | gmane.comp.web.zope.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi there, I've been really getting my head around Zope3 and adaption lately for a talk for my local Python usergroup. I've read quite a bit on the topic, but of particular interest was the adapter vs. generic function debate that's been doing the rounds over the last few years. See Guido van Rossum's article here: http://www.artima.com/weblogs/viewpost.jsp?thread=155123 where he concludes that generic functions are more general and useful. Further, we have Ian Bicking's Zope 3 critique where, he argues that generic functions are generally better and Martijn Faassen's comment: "I agree by the way that generic methods are interesting and we should be investigating how they fit in a Zope 3 context." There is a clear relationship between the two, and after some brainstorming with Chris McDonough on the Zope IRC channel, I've been able to write an @generic(TypeA, TypeB, ... , TypeN) decorator that uses the Zope component registry to supply such behaviour. It's become clear to me that named multiadapters are essentially the same concept as generic functions, and in a Zope context, are actually more powerful because you can specify *interfaces* as well as concrete types as part of the function's type-signature: @generic(IFoo, IBar, TypeA, TypeB, ...). I don't know if this relationship is already known in the Zope world, and if people are already doing this? Is there any value in something like this? It's pretty 'deep' stuff, so I've written a tutorial (Chris's idea) that goes through the thought process towards writing the generic function decorator with Zope tools - please find attached. We think it might make a nice (supplementary) addition to upcoming zope.component narrative documentation (there is upcoming documentation... right?). To confirm the idea I wrote a basic little script too, which I've attached also. You can see that @generic works with types, interfaces or both - thanks to the zope.component machinery. Any thoughts would be great! Paul _______________________________________________ Zope-Dev maillist - [email protected] https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )
generic_functions_zca.rst
(application/octet-stream, 12.2 KB) - not displayed
genericfuncs.py
(text/x-python, 1.4 KB)
from zope.interface import implementer, Interface, implements
from zope.component import getSiteManager, getMultiAdapter
from zope.component import adapter
class IGenericFunction(Interface):
"""
Marker interface. Any interface would do though.
"""
class IFoo(Interface):
pass
class IBar(Interface):
pass
class Foo(object):
implements(IFoo)
class Bar(object):
implements(IBar)
def generic(*type_sig):
def register(gen_func):
name = gen_func.__name__
def new_func(*args):
obj = getMultiAdapter(args, IGenericFunction, name=name)
return obj
implementer(IGenericFunction)(gen_func)
adapter(type_sig)(gen_func)
sm = getSiteManager()
sm.registerAdapter(gen_func, type_sig, name=name)
new_func.__name__ = name
return new_func
return register
if __name__ == '__main__':
@generic(int, int)
def funcy(a, b):
return "Ints: %d, %d" % (a, b)
@generic(str, str)
def funcy(a, b):
return "Strings: %s, %s" % (a, b)
foo = Foo()
bar = Bar()
@generic(IFoo)
def funcy(a):
return "I got an IFoo"
@generic(IBar)
def funcy(a):
return "I got an IBar"
@generic(IFoo, int)
def funcy(f, a):
return "I got an IFoo and int: %d" % a
print funcy(1,2)
print funcy("a", "b")
print funcy(foo)
print funcy(bar)
print funcy(foo, 10)
print funcy.__name__