1

I'm trying to write a python function decorator, and part of my implementation is that I need to capture the function call and look through the supplied values. I already have the function signature by using inspect.signature, but I'm unsure how to compose it with passed arguments.

Say I had the following

def decorator(func):
    def wrapper(*args, **kwargs):
        print(some_function_signature_getter(func, *args, **kwargs))
        return func(*args, **kwargs)
    return wrapper


@decorator
def foo(a, b, *_, **kwargs):
    return a+b

print(foo(1, 2))

How can I implement some_function_signature_getter such that my output is something like the following:

{'a': 1, 'b': 2, '_':[], 'kwargs':{}}
3
user852541
  • 55
  • 6
  • What research have you done? Have you seen this: [How can I read a function's signature including default argument values?](/q/2677185/4518341) – wjandrea May 21 '22 at 22:19
  • @wjandrea seems like a duplicate to me. – Karl Knechtel May 21 '22 at 22:20
  • 1
    @KarlKnechtel that covers getting the signature, but not binding a given call's arguments to see what goes where (not that this might not still be a dupe, but that's certainly not _all_ of it). – jonrsharpe May 21 '22 at 22:24
  • 1
    @wjandrea I am using signature I just haven't figured out how to compose it with the passed arguments – user852541 May 21 '22 at 22:34
  • 2
    @user852541 note if you'd included that information in the post it would have been less likely to get closed as a duplicate (of the current target, at least). Right now `inspect` isn't referred to at all. – jonrsharpe May 21 '22 at 22:35
  • 1
    @jonrsharpe Thank you for the criticism, I appreciate it – user852541 May 21 '22 at 22:39

1 Answers1

-1

Whenever you want to introspect function/method signatures, you can use inspect.signature. In this case:

from inspect import signature

def decorator(func):
    sig = signature(func)
    def wrapper(*args, **kwargs):
        bound = sig.bind(*args, **kwargs)
        bound.apply_defaults()
        print(bound.arguments)
        return func(*args, **kwargs)
    return wrapper

*args are a tuple, not a list, but otherwise this gives you what you want:

>>> print(foo(1, 2))
{'a': 1, 'b': 2, '_': (), 'kwargs': {}}
3
jonrsharpe
  • 107,083
  • 22
  • 201
  • 376