[Python-ideas] Specifying constants for functions
Ryan Gonzalez
rymg19 at gmail.com
Tue Oct 27 16:15:24 EDT 2015
Making a decorator is easy:
def opt(**kw):
def func(f):
globals().update(dis.opmap) # Someone's going to kill me for this...
code = list(f.__code__.co_code)
offs = 0
varnames = list(f.__code__.co_varnames)
nlocals = f.__code__.co_nlocals
names = list(f.__code__.co_names)
globls = f.__globals__
mapping = {}
anon_count = 0
for k, v in kw.items():
if k in names:
try:
i = names.index(k)
except ValueError:
raise ValueError('variable %r must be a global' % k)
from None
anon_var = '$__varopt__%d$' % anon_count
anon_count += 1
names[i] = anon_var
globls[anon_var] = v
assert k not in varnames, '%r is both global and local' % k
varnames.append(k)
nlocals += 1
mapping[i] = nlocals-1
code[:0] = [
LOAD_GLOBAL, i, 0,
STORE_FAST, nlocals-1, 0,
]
offs += 6
else:
raise ValueError('variable %r is not a global' % k)
i = offs
while i < len(code):
if code[i] in dis.hasjabs:
code[i+1] += offs
elif code[i] in (LOAD_GLOBAL, STORE_GLOBAL) and code[i+1] in
mapping:
code[i] = LOAD_FAST if code[i] == LOAD_GLOBAL else
STORE_FAST
code[i+1] = mapping[code[i+1]]
i += 3 if code[i] > dis.HAVE_ARGUMENT else 1
rescode = types.CodeType(f.__code__.co_argcount,
f.__code__.co_kwonlyargcount, nlocals,
f.__code__.co_stacksize,
f.__code__.co_flags,
bytes(code), f.__code__.co_consts,
tuple(names), tuple(varnames),
f.__code__.co_filename, f.__code__.co_name,
f.__code__.co_firstlineno,
f.__code__.co_lnotab,
f.__code__.co_freevars,
f.__code__.co_cellvars)
return types.FunctionType(rescode, globls,
f.__name__, f.__defaults__, f.__closure__)
return func
On Tue, Oct 27, 2015 at 12:45 PM, Serhiy Storchaka <storchaka at gmail.com>
wrote:
> There is known trick to optimize a function:
>
> def foo(x, y=0, len=len, pack=struct.pack, maxsize=1<<BPF):
> ...
>
> It has a side effect: change function's signature. Would be nice to have a
> way to set function's local variables at creation time without affecting a
> signature.
>
> Possible syntax (I'm not sure what is better):
>
> 1. Similar to "global" and "nonlocal" declarations with optional
> initializer.
>
> def foo(x, y=0):
> const len
> const pack=struct.pack, maxsize=1<<BPF
> ...
>
> 2. Same as 1, but using "as" instead of "=".
>
> def foo(x, y=0):
> uses len, struct.pack as pack
> uses 1<<BPF as maxsize
> ...
>
> 3. Declaration is moved to function header. The keyword "given" is
> inspired by PEP 3150.
>
> def foo(x, y=0) given len=len, pack=struct.pack, maxsize=1<<BPF:
> ...
>
> 4. Declaration is moved out of the function. The advantage is that bound
> names can be used to evaluate default values for actual parameters (it is
> useful to implement sentinel default value), and all expression are
> evaluated in natural order.
>
> using len, struct.pack as pack, 1<<BPF as maxsize:
> def foo(x, y=0):
> ...
>
> 5. The least wordy syntax. No new keyword needed.
>
> def foo(x, y=0; len=len, pack=struct.pack, maxsize=1<<BPF):
> ...
>
> All above examples would be roughly equivalent to the following code:
>
> def create(len=len, pack=struct.pack, maxsize=1<<BPF):
> def foo(x, y=0):
> ...
> return foo
> tmp = create()
> def foo(x, y=0):
> pass
> update_wrapper(tmp, foo)
> foo = tmp
> del create, tmp
>
> This feature is rather ideologically opposite to Victor's approach.
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
--
Ryan
[ERROR]: Your autotools build scripts are 200 lines longer than your
program. Something’s wrong.
http://kirbyfan64.github.io/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151027/4a089f05/attachment.html>
More information about the Python-ideas
mailing list