[Python-ideas] 'Injecting' objects as function-local constants

Steven D'Aprano steve at pearwood.info
Fri Jun 17 07:37:46 CEST 2011


Nick Coghlan wrote:
> On Fri, Jun 17, 2011 at 3:15 AM, Jan Kaliszewski <zuo at chopin.edu.pl> wrote:
>> or even (to stress that it is a language syntax construct:
>>>> @inject mem=collections.Counter(), MAX_MEM=1000
>> def do_and_remember(val, verbose=False):
>> While that would require the from__future__ dance to make "inject" a
> new keyword, I like it much better than the
> looks-like-a-decorator-but-isn't syntax.

What benefit is there in making inject a keyword? Even super isn't a 
keyword.
As far as I'm concerned, inject need only be a function in the functools 
module, not even a built-in, let alone a keyword.
Here's a quick and dirty version that comes close to the spirit of 
inject, as I see it. Thanks to Alex Light's earlier version.
# Credit to Alex Light.
from contextlib import contextmanager
from functools import wraps
def inject(**localArgs):
 def decorator(func):
 glbs = func.__globals__
 @wraps(func)
 def inner(*args, **kwargs):
 with _modifyGlobals(glbs, localArgs):
 ret = func(*args, **kwargs)
 return ret
 return inner
 return decorator
@contextmanager
def _modifyGlobals(glbls, additions):
 frmglbls = glbls.copy()
 try:
 glbls.update(additions)
 yield
 finally:
 glbls.clear()
 glbls.update(frmglbls)
And demonstrating it in use:
 >>> def func(obj):
... print(len)
... return len(obj)+1
...
 >>> import builtins
 >>> newfunc = inject(len=lambda o: print(o) or builtins.len(o))(func)
 >>>
 >>> func([]) # Original function unchanged, still uses uninjected len.
<built-in function len>
1
 >>> newfunc([]) # New function uses injected len.
<function <lambda> at 0xb7c2f86c>
[]
1
And as a decorator:
 >>> @inject(a=1)
... def spam():
... print(a)
...
 >>> a = 42
 >>> spam()
1
Unfortunately, this proof-of-concept inject function doesn't actually 
inject into locals, hence the "import builtins" work-around. But it 
demonstrates the intent, and the API.
-- 
Steven


More information about the Python-ideas mailing list

AltStyle によって変換されたページ (->オリジナル) /