Well we don't actually need inspect here.
>>> func = lambda x, y: (x, y)
>>>
>>> func.__code__.co_argcount
2
>>> func.__code__.co_varnames
('x', 'y')
>>>
>>> def func2(x,y=3):
... print(func2.__code__.co_varnames)
... pass # Other things
...
>>> func2(3,3)
('x', 'y')
>>>
>>> func2.__defaults__
(3,)
Answer from simplyharsh on Stack OverflowWell we don't actually need inspect here.
>>> func = lambda x, y: (x, y)
>>>
>>> func.__code__.co_argcount
2
>>> func.__code__.co_varnames
('x', 'y')
>>>
>>> def func2(x,y=3):
... print(func2.__code__.co_varnames)
... pass # Other things
...
>>> func2(3,3)
('x', 'y')
>>>
>>> func2.__defaults__
(3,)
locals() returns a dictionary with local names:
def func(a, b, c):
print(locals().keys())
prints the list of parameters. If you use other local variables those will be included in this list. But you could make a copy at the beginning of your function.
Getting all arguments from a function call in python
Get exact function call keyword arguments in order
python - Getting all arguments and values passed to a function - Stack Overflow
Get names of positional arguments in wrapping function
Hello,
Im trying to find out if there is a way to access all arguments passed to a function (perhaps in a dictionary) from within a function? Does anyone know a way to do this?
For example if I have
def myfunc(a,b,c,d):
passIs there some line of code I can use that will let me gather all the arguments passed into a list or a dictionary?
Thanks
Essentially, I'm trying to work out how to, from within a function, get a completely populated *args and **kwargs, including the function's named parameters.
How about saving the arguments via locals() at the beginning of the function?
def my_func(a, *args, **kwargs):
saved_args = {**locals()} # Updated to make a copy per loco.loop
print("saved_args is", saved_args)
local_var = 10
print("saved_args is", saved_args)
print("But locals() is now", locals())
my_func(20, 30, 40, 50, kwarg1='spam', kwarg2='eggs')
It gives this output:
saved_args is {'a': 20, 'args': (30, 40, 50), 'kwargs': {'kwarg1': u'spam', 'kwarg2': u'eggs'}}
saved_args is {'a': 20, 'args': (30, 40, 50), 'kwargs': {'kwarg1': u'spam', 'kwarg2': u'eggs'}}
But locals is now {'a': 20, 'saved_args': {...}, 'args': (30, 40, 50), 'local_var': 10, 'kwargs': {'kwarg1': u'spam', 'kwarg2': u'eggs'}}
Hat tip: https://stackoverflow.com/a/3137022/2829764
Not something I'd do, but you could use inspect.signature to introspect the arguments your method takes:
>>> import inspect
>>> def foobar(foo, bar, baz):
... return inspect.signature(foobar)
...
>>> foobar(1, 2, 3)
<Signature (foo, bar, baz)>
The returned Signature instance has an ordered collection of parameters (the .parameters attribute) which can then be used together with locals() to produce a list of your argument values:
>>> def foobar(foo, bar, baz):
... sig, foobar_locals = inspect.signature(foobar), locals()
... return [foobar_locals[param.name] for param in sig.parameters.values()]
...
>>> foobar(1, 2, 3)
[1, 2, 3]
However, you really only need such magic when doing advanced function decorators and the like. I think it's overkill here.
You can use locals() to get a dict of the local variables in your function, like this:
def foo(a, b, c):
print locals()
>>> foo(1, 2, 3)
{'a': 1, 'c': 3, 'b': 2}
This is a bit hackish, however, as locals() returns all variables in the local scope, not only the arguments passed to the function, so if you don't call it at the very top of the function the result might contain more information than you want:
def foo(a, b, c):
x = 4
y = 5
print locals()
>>> foo(1, 2, 3)
{'y': 5, 'x': 4, 'c': 3, 'b': 2, 'a': 1}
I would rather construct a dict or list of the variables you need at the top of your function, as suggested in the other answers. It's more explicit and communicates the intent of your code in a more clear way, IMHO.
Here's a function you can call to get the kwargs of the current function. Or if you want to use those lines directly in your own function instead of calling get_kwargs() just remove the .f_back
import inspect
def get_kwargs():
frame = inspect.currentframe().f_back
keys, _, _, values = inspect.getargvalues(frame)
kwargs = {}
for key in keys:
if key != 'self':
kwargs[key] = values[key]
return kwargs
def test(x, y=100):
z = 7
print(get_kwargs())
test(5, 6)
# Output: {'x': 5, 'y': 6}
test(5)
# Output: {'x': 5, 'y': 100}