[Python-ideas] 'Injecting' objects as function-local constants
Jan Kaliszewski
zuo at chopin.edu.pl
Thu Jun 16 01:15:36 CEST 2011
Steven D'Aprano dixit (2011-06-15, 21:35):
> This is another reason why function parameters should not be used for
> something that is not a function parameter!
>
> +1 on the ability to inject locals into a function namespace.
>
> -1 on having the syntax for that masquerade as function arguments.
OK, so the decorator or decorator-like syntax (using 'inject', 'within',
'owns' or other decorator name...) seems to be the most promising
alternative. If so, next question is: which variant?
1. Decorator function with closure-like injecting
(possibly could be implemented using closures):
@functools.owns(cache=dict(), MAX_CACHE_LEN=100)
def calculate(a, b):
result = cache[(a, b)]
if result is not None:
return result
...
# 'cache' identifier cannot be rebound to another object
# because it was already used above in the function body
# to refer to the injected object
functools.owns() would be a real decorator function -- to apply either with
@-syntax or dynamically, e.g.:
decorated = [functools.owns(func) for func in functions]
One question is whether it is technically possible to avoid introducing
a new keyword (e.g. staticlocal) explicitly marking injected locals.
Using such a keyword would be redundant from user point of view and
non-DRY:
@functools.owns(cache=dict(), MAX_CACHE_LEN=100)
def calculate(a, b):
staticlocal cache, MAX_CACHE_LEN # <- redundant and non-DRY :-(
result = cache[(a, b)]
if result is not None:
return result
...
2. Decorator function with argument-like injecting.
@functools.owns(cache=dict(), MAX_CACHE_LEN=100)
def calculate(a, b):
result = cache[(a, b)]
if result is not None:
return result
...
# 'cache' identifier *can* be rebound to another object
# than the injected object -- in the same way arguments can
functools.owns() would be a real decorator function -- to apply either with
@-syntax or dynamically, e.g.:
decorated = [functools.owns(func) for func in functions]
To implement such variant -- a new function constructor argument(s)
and/or function/function code attribute(s) (read-only or writable?)
most probably would have to be introduced...
3. Decorator-like language syntax construct:
@in(cache=dict(), MAX_CACHE_LEN=100) # or 'owns' or 'inject' or...
def calculate(a, b):
result = cache[(a, b)]
if result is not None:
return result
...
# 'cache' identifier *can* be rebound to another object
# than the injected object -- in the same way arguments can
It would not be a real decorator function -- so it would be applicable
only using this syntax, and not dynamically, not after function creation.
Which do you prefer? (or any other?)
Regards.
*j
More information about the Python-ideas
mailing list