Inferring initial locals()
George Sakkis
george.sakkis at gmail.com
Thu Jun 21 17:35:16 EDT 2007
On Jun 21, 4:42 pm, "bruno.desthuilli... at gmail.com"
<bruno.desthuilli... at gmail.com> wrote:
> On Jun 21, 8:51 pm, George Sakkis <george.sak... at gmail.com> wrote:
>
>
>
> > I wonder if there is a (preferably not too-hackish) solution to the
> > following introspection problem: given a callable and a number of
> > positional and/or keyword arguments, infer what would be the frame's
> > locals() right after the function is called. For example, given:
>
> > def f(x, y=1, *a, **k):
> > z = x + y
> > w = len(a) - len (k)
> > return z * w
>
> > I'd like to have a function
>
> > def get_init_locals(callable, *args, **kwds):
> > # TODO
> > pass
>
> > so that:
>
> > >>> get_init_locals(f, 3)
>
> > {'a': (), 'k': {}, 'x': 3, 'y': 1}
>
> You might be intersted in the 'inspect' module.
Turns out it wasn't that hard after all; I came up with the following:
import types, inspect
from itertools import islice, izip
def localsProber(callable):
args, varargs, varkw, defaults = inspect.getargspec(callable)
if defaults is None: defaults = ()
# create a function with the same signature as the callable and
# "return locals()" for body
context = {'__builtins__': {'locals': locals}}
iterargs = iter(args)
# - first all the required args
sig_args = list(islice(iterargs, len(args)-len(defaults)))
# - then all the default args
for arg,default in izip(iterargs,defaults):
context[arg] = default
sig_args.append('%s=%s' % (arg,arg))
# - then variable positional and keyword args (if any)
if varargs: sig_args.append('*' + varargs)
if varkw: sig_args.append('**' + varkw)
name = callable.__name__
exec 'def %s(%s): return locals()' % (name, ', '.join(sig_args))
in context
prober = context[name]
if inspect.ismethod(callable): # return a method if callable is a
method
prober = types.MethodType(prober, callable.im_self,
callable.im_class)
return prober
>>> def f(x, y=1, *a, **k): pass
...
>>> get_f_locals = localsProber(f)
>>> get_f_locals(3)
{'a': (), 'k': {}, 'x': 3, 'y': 1}
>>> get_f_locals(3,4,5)
{'a': (5,), 'k': {}, 'x': 3, 'y': 4}
>>> get_f_locals(3,q=-1)
{'a': (), 'k': {'q': -1}, 'x': 3, 'y': 1}
George
More information about the Python-list
mailing list