generator expressions: performance anomaly?

Steven Bethard steven.bethard at gmail.com
Wed Jan 19 04:03:07 EST 2005


Stephen Thorne wrote:
> On Tue, 18 Jan 2005 23:09:57 -0700, Steven Bethard
> <steven.bethard at gmail.com> wrote:
> 
>>@with_consts(i=1, deftime=time.ctime())
>>def foo(x, y=123, *args, **kw):
>>     return x*y, kw.get('which_time')=='now' and time.ctime() or deftime
>>
>>Then you don't have to mix parameter declarations with locals definitions.
>>
>>[1] I have no idea how implementable such a decorator would be.  I'd
>>just like to see function constants declared separate from arguments
>>since they mean such different things.
> 
> 
> (untested)
> 
> def with_constant(**constants_kwargs):  
>   def decorator(f)
>     def closure(*arg, **kwargs):
>       kwargs.update(constants_kwargs)
>       return f(*arg, **kwargs)
>     return closure
>   return decorator

This doesn't quite work because it still requires that f take the 
constants as parameters:

py> def with_constant(**constants_kwargs):
...     def decorator(f):
...         def closure(*arg, **kwargs):
...             kwargs.update(constants_kwargs)
...             return f(*arg, **kwargs)
...         return closure
...     return decorator
...
py> @with_constant(x=1)
... def f(y):
...     return x + y
...
py> f(1)
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "<interactive input>", line 5, in closure
TypeError: f() got an unexpected keyword argument 'x'

I screwed around for a while with:
     ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(frame), 0)
which will let you propagate updates made to frame.f_locals, but only if 
you don't *add* any locals to the frame, as far as I can tell:

py> def f(x=1):
...     frame = sys._getframe()
...     frame.f_locals["x"] = 2
...     print x
...
py> f()
1
py> def f(x=1):
...     frame = sys._getframe()
...     frame.f_locals["x"] = 2
...     ctypes.pythonapi.PyFrame_LocalsToFast(
...         ctypes.py_object(frame), 0)
...     print x
...
py> f()
2
py> def f(x=1):
...     frame = sys._getframe()
...     frame.f_locals["y"] = 2
...     ctypes.pythonapi.PyFrame_LocalsToFast(
...         ctypes.py_object(frame), 0)
...     print y
...
py> f()
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "<interactive input>", line 6, in f
NameError: global name 'y' is not defined

Steve



More information about the Python-list mailing list