Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number of actual function arguments

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?

like image 216
georg Avatar asked Oct 25 '13 12:10

georg


People also ask

How do you find the number of arguments in a function?

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.

How many function arguments are there?

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.

What are actual arguments?

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.

How many arguments can a function receive?

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.


2 Answers

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. :-)

like image 53
Martijn Pieters Avatar answered Sep 29 '22 22:09

Martijn Pieters


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.

like image 43
Alexander Zhukov Avatar answered Sep 30 '22 00:09

Alexander Zhukov