PEP: Specialization Syntax
Bengt Richter
bokr at oz.net
Mon Aug 8 20:14:25 EDT 2005
On Mon, 08 Aug 2005 16:18:50 -0400, Nicolas Fleury <nid_oizo at yahoo.com_removethe_> wrote:
>Bengt Richter wrote:
>> On Sun, 07 Aug 2005 21:41:33 -0400, Nicolas Fleury <nid_oizo at yahoo.com_removethe_> wrote:
>>>I mean should angle brackets <> like in C++, or another operator, be
>>>used instead?
>>
>> I am getting the feeling that your PEP is about a means to do something C++-like
>> in python, not necessarily to enhance python ;-) IOW, it seems like you
>> want the [<new syntax>] to do something like C++ <type_spec> in templates?
>
>Yes, exactly. Actually Guido also mentionned pointy brackets:
>http://www.artima.com/weblogs/viewpost.jsp?thread=86641
>
>> (BTW, I have nothing against giving python new capabilities (quite the reverse),
>> but not by grafting limbs from other animals ;-)
>
>If I look at a very recent blog entry of Guido, it seems the idea is
>still in the air:
>http://www.artima.com/weblogs/viewpost.jsp?thread=92662
>
>> Maybe you want hidden name-mangling of function defs according to arg types
>> and corresponding dispatching of calls? I am afraid I am still not clear
>> on the fundamental motivation for all this ;-)
>
>I wrote the PEP to see if was the only one that would benefit from
>generic types *before* having optional static typing in the language.
>
>It seems I'm the only one;)
>
>According to blog entry 86641, Guido himself is prototyping with
>__getitem__. However, I cannot do the same, because the framework I use
>is much more complete and keyword arguments are a must.
>
Here is a decorator object to set up function call dispatch according to type.
It only uses positional arguments, but could be fleshed out, I think.
Not tested beyond what you see ;-)
----< typedispatcher.py >-------------------------------------------------
# typedispatcher.py
"""
Provides a decorator to dispatch function
calls according to arg types and signature.
Example usage:
foodisp = TypeDispatcher() # instance dedicated to foo variants
@foodisp(a=int, b=str)
def foo(a, b):
assert type(a) is int and type(b) is str
return (a,b)
@foodisp(a=str, b=str)
def foo(a, b):
assert type(a) is str and type(b) is str
return (a,b)
"""
class TypeDispatcher(object):
def __init__(self):
self.dispdict = {}
def __call__(self, **kwtypes):
self.kwtemp = kwtypes
return self.dodeco
def dodeco(self, f):
if not hasattr(self, 'name'):
self.name = f.func_name
if f.func_name != self.name:
raise ValueError('This TypeDispatcher instance decorates only functions named %r' % self.name)
sig = tuple((self.kwtemp[argname] for argname in f.func_code.co_varnames[:f.func_code.co_argcount]))
assert len(set([f.func_name]+list(f.func_name for f in self.dispdict.values())))
self.dispdict[sig] = f
return self.docall
def docall(self, *args):
sig = tuple(map(type, args))
try: f = self.dispdict[sig]
except KeyError:
raise TypeError('no function %r with signature %r' % (self.name, sig))
return f(*args)
def test():
try:
foodisp = TypeDispatcher()
@foodisp(a=int, b=str)
def foo(a, b):
assert type(a) is int and type(b) is str
return 'foo(int, str):', (a,b)
@foodisp(a=str, b=str)
def foo(a, b):
assert type(a) is str and type(b) is str
return 'foo(str, str):', (a,b)
@foodisp()
def foo():
return 'foo()', ()
print foo(123, 'hello')
print foo('hi','there')
print foo()
print foo(456, 789)
except Exception, e:
print 'Exception %s: %s' % (e.__class__.__name__, e)
try:
@foodisp()
def bar(): pass
except Exception, e:
print 'Exception %s: %s' % (e.__class__.__name__, e)
if __name__ == '__main__':
test()
--------------------------------------------------------------------------
Result:
[17:12] C:\pywk\ut>py24 typedispatcher.py
('foo(int, str):', (123, 'hello'))
('foo(str, str):', ('hi', 'there'))
('foo()', ())
Exception TypeError: no function 'foo' with signature (<type 'int'>, <type 'int'>)
Exception ValueError: This TypeDispatcher instance decorates only functions named 'foo'
Regards,
Bengt Richter
More information about the Python-list
mailing list