The number of arguments to the actual function

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 his signature to accept *args ?

+6
source share
3 answers

You can change the default value for the sentry:

 _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 in fact it is not used; this will just confuse those who are not familiar with the standard attributes of a function object.

Yes, the _sentinel object is introspective and can be obtained by a specific developer, but then the same developer can simply disable your function. _sentinel

+6
source

You can use a decorator for this. From Saving the signatures of the issued functions, 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 just added a keyword argument for the number of arguments we passed to the function. As you can see, by default it is 1, which is True. It seems like a hack, but it works.

+6
source

I would use a decorator:

 def wrapper(func): def wrapped(*args): if len(args) == 2: print "2 arg" else: print "1 arg" return wrapped @wrapper def foo(a,optional=None): pass foo(11) #1 arg foo(22, 42) #2 arg 
0
source

Source: https://habr.com/ru/post/956709/


All Articles