4

Given the following function:

def test(* p1=None, p2=None):
  ...

Called as follows:

test(p2="hello")

Can I programmatically obtain a list/dictionary of the arguments and their value at runtime?

1: Don't want to use **kwargs because I want to force the user to use the proper argument names (and plan to do type annotation as well).

2: I've looked at the inspect module for getting the defaults, but does not seem to let me see the run-time values.

Looking to create code something like this:

request = {k: v for k,v in __some_magic_location__ if v is not None}
Ma0
  • 15,057
  • 4
  • 35
  • 65
rgacote
  • 408
  • 2
  • 10
  • 1
    `* p1=None` is a SyntaxError. Did you mean `*, p1=None`? – Aran-Fey Jan 24 '18 at 16:21
  • Can you modify the definition of the `test` function? – Ma0 Jan 24 '18 at 16:26
  • So, in that case, would you want an output of `{"p2": "hello"}` or `{"p1": None, "p2": "hello"}?` – internet_user Jan 24 '18 at 16:26
  • A pity it's closed now, but I don't want to un-dupe-hammer it open, either. Just wanted to suggest using a decorator `def deco(f): def _f(**kwargs): print("PARAMS:", kwargs) return f(**kwargs) return _f` and then `@deco def test(...)`; this way, you can use `kwargs` to print the arguments, and at the same time prevent the user from passing invalid keyword-arguments or arguments without a name. – tobias_k Jan 24 '18 at 16:34

2 Answers2

4

Use locals:

>>> def test(*, p1=None, p2=None):
...     return locals()
...
>>> test(p2='hello')
{'p1': None, 'p2': 'hello'}
Vincent
  • 12,919
  • 1
  • 42
  • 64
1

You can use inspect.getcallargs:

import inspect
def test(*, p1=None, p2=None):
  pass

print(inspect.getcallargs(test, p2 = 'Hello'))

Output:

{'p2': 'Hello', 'p1': None}
Ajax1234
  • 69,937
  • 8
  • 61
  • 102