Steven D'Aprano wrote:
> Proposal:
> We should have a mechanism that collects the current function or
> method's parameters into a dict, similar to the way locals() returns all
> local variables.
> This mechanism could be a new function,or it could even be a magic local
> variable inside each function, similar to what is done to make super()
> work. But for the sake of this discussion, I'll assume it is a function,
> parameters(), without worrying about whether it is a built-in or
> imported from the inspect module.
> So given a function signature:
> def func(spam, eggs, cheese=None):
>
> and a call to it func(1, 2), then inside the body of the function,
> calling parameters() will return the dict:
> {'spam': 1, 'eggs': 2, 'cheese': None}
> [...]
> Another pattern would be to pass on your parameters to the superclasses:
> super().method(**parameters())
I took a stab at this. This should work regardless of where the function is
defined.
```
import inspect
def parameters(*, expand_kwargs=True):
frame = inspect.currentframe().f_back
code = frame.f_code
varnames = code.co_varnames
end = code.co_argcount + code.co_kwonlyargcount
result = {
name: frame.f_locals[name]
for name in varnames[:end]
}
# **kwargs
if code.co_flags & inspect.CO_VARKEYWORDS:
index = end
if code.co_flags & inspect.CO_VARARGS:
index += 1
name = varnames[index]
var = frame.f_locals[name]
if expand_kwargs:
result.update(var)
else:
result[var] = name
return result
def foo1(a, b=1, *args, c, **d):
x = 1
y = 2
print(parameters())
print(a, b, c, d)
foo2(**parameters())
def foo2(a, b=1, *args, c, **d):
print(a, b, c, d)
foo1(1, 2, 3, 4, c=5, e=6, f=7)
```
Output:
```
{'a': 1, 'b': 2, 'c': 5, 'e': 6, 'f': 7}
1 2 5 {'e': 6, 'f': 7}
1 2 5 {'e': 6, 'f': 7}
```
Note that `parameters()` intentionally doesn't contain `'args': (3, 4)`
because then `foo2(**parameters())` would see `args` as a keyword argument
within `d` instead of bound to the parameter `*args`. So naturally I tried
`foo2(*args, **parameters())` but that gave me `TypeError: foo2() got
multiple values for argument 'a'`. So if you want to pass all arguments
from one function to another, you need more than a dict if the inner
signature include `*args`, and obviously even more so if it includes
positional only parameters.
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/QQKU24OU67ZPPFSWJHN7OCJXR7V2Z62A/
Code of Conduct: http://python.org/psf/codeofconduct/