Is there a way to get the number of actual parameters passed to a function
def foo(a, optional=42):
if ????
print "1 arg"
else:
print "2 args"
foo(11) # should print 1 arg
foo(22, 42) # should print 2 args
without changing its signature to accept *args
?
Syntax *args allow us to pass a variable number of arguments to a function. We will use len() function or method in *args in order to count the number of arguments of the function in python.
Except for functions with variable-length argument lists, the number of arguments in a function call must be the same as the number of parameters in the function definition. This number can be zero. The maximum number of arguments (and corresponding parameters) is 253 for a single function.
The arguments that are passed in a function call are called actual arguments. These arguments are defined in the calling function. These are the variables or expressions referenced in the parameter list of a subprogram call. There is no need to specify datatype in actual parameter.
Arguments are specified after the function name, inside the parentheses. You can add as many arguments as you want, just separate them with a comma.
You could change the default value to a sentinel:
_sentinel = object()
def foo(a, optional=_sentinel):
if optional is _sentinel:
optional = 42
print "1 arg"
else:
print "2 args"
or by accessing it directly in the func_defaults
tuple:
def foo(a, optional=object()):
if optional is foo.func_defaults[0]:
optional = 42
print "1 arg"
else:
print "2 args"
but don't actually use that; that'll just serve to confuse those not familiar with standard function object attributes.
Yes, the _sentinel
object is introspectable and can be obtained still by a determined developer, but then again that same developer could just monkeypatch your function as well. :-)
You can use a decorator to do that. From the Preserving signatures of decorated functions question we know how to do this correctly.
import decorator
@decorator.decorator
def count_args(f):
def new(*args, **kwargs):
kwargs['nargs'] = len(args)+len(kwargs)
return f(*args, **kwargs)
return new
@count_args
def foo(a, optional=42, nargs=1):
print nargs
foo(1) # 1
foo(1, 4) # 2
foo(1, optional=4) # 2
Update:
I have just added keyword argument for the number of args, that we passed to the function. As you can see, by default it is 1, which is True. This looks like a hack, but it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With