I'm trying to understand the following about dealing with functions and their arguments:
def print_my_arg(func, *args, **kwargs):
func(*args, **kwargs)
if 'my_arg' in kwargs:
print(' my_arg = {}'.format(kwargs['my_arg']))
def foo(call_no, my_arg='Default Value'):
print('call_no = {}'.format(call_no) )
print_my_arg(foo, 0, my_arg='My Value 1')
print_my_arg(foo, 1, 'My Value 2')
print_my_arg(foo, 2)
Output:
call_no = 0
my_arg = My Value 1
call_no = 1 # I'd like to see 'My Value 2' here
call_no = 2 # I'd like to see 'Default Value' here
Obviously people are free to invoke functions in either of the ways shown above, which makes me wonder: why my_arg doesn't go to kwargs anyway? Isn't there a uniform way to access parameters by name (and not by position), which doesn't depend on the way the function was invoked?
Please note that:
I'm not interested in
print_my_args(func, call_no, my_arg), because I'm talking about the case where I don't know the signature offuncin advance and yet I want to know if a particular parameter exists (by name).Clearly that's related to decorators, but I've written the example in a simpler way (or I hope so).
EDIT
Many thanks for the answers about inspect.signature. Using that, my new version of print_my_arg() is:
from inspect import signature
def print_my_arg ( func, *args, **kwargs ):
func ( *args, **kwargs )
sig = signature ( func )
if 'my_arg' not in sig.parameters: return
binding = sig.bind ( *args, **kwargs )
binding.apply_defaults ()
print ( " my_arg = {}".format ( binding.arguments [ 'my_arg' ] ) )
**kwargs, because they're not keyword arguments. If you want to pass the second positional argument to the function, you'll have to do that explicitly, it's not at all clear why you expected different behaviour. You could force keyword arguments if you really wanted to, see e.g. stackoverflow.com/a/37829651/3001761signatureof the function to check the argument name inprint_my_args? then you could dopassed_args = inspect.signature(func).bind(*args,**kwargs)then check ifmy_argis inpassed_args.