Common function in python - calling a method with an unknown number of arguments

I am new to python and need some help ...

I am implementing a universal search function that takes an argument of "fringe", which can be a data structure of many types.

in the search method, I have a line:

fringe.push(item, priority) 

the problem is that the push method in different data structures takes a different number of arguments (some require priority, and some do not). Is there a more flexible way to get the pass and force the push method to take only the number of arguments it requires from the argument list?

Thanks!

+6
source share
4 answers

The method of obtaining a different number of arguments and the ability to choose the right one is to use the * args and ** keyword_args parameters. From Mark Lutz's Learning Python book:

* and ** are intended to support functions that take any number of arguments. Both can be displayed either in a function definition or in a function call, and they have related goals in two places.

* and ** in function definition

If you define a function:

 def f1(param1, *argparams, **kwparams): print 'fixed_params -> ', param1 print 'argparams --> ', argparams print 'kwparams ---->,', kwparams 

you can call it like this:

 f1('a', 'b', 'c', 'd', kw1='keyw1', kw2='keyw2') 

Then you will get:

 fixed_params -> a argparams --> ('b', 'c', 'd') kwparams ---->, {'kw1': 'keyw1', 'kw2': 'keyw2'} 

So you can send / receive any number of parameters and keywords. One typical idiom for recovering args keywords is as follows:

 def f1(param1, **kwparams): my_kw1 = kwparams['kw1'] ---- operate with my_kw1 ------ 

Thus, your function can be called with any number of parameters, and it uses those that it needs.
This type or arguments are often used in some graphical interface, such as the wxPython class and subclass definition, as well as for currying functions, decorators, etc.

* and ** in function call

* and ** params in the function call are unpacked when the function is executed:

 def func(a, b, c, d): print(a, b, c, d) args = (2, 3) kwargs = {'d': 4} func(1, *args, **kwargs) ### returns ---> 1 2 3 4 

Excellent!

+7
source

In theory, you can use inspect.getargspec(fringe) to find out what arguments the method takes. This will tell you the number of arguments you could pass, but it is very dirty:

 argspec = inspect.getargspec(fringe.push) if len(argspec.args) >= 3 or argspec.varargs or argspec.keywords: fringe.push(item, priority) else: fringe.push(item) 

It’s much easier to just go for it and ask for forgiveness if necessary:

 try: fringe.push(item, priority) except TypeError: fringe.push(item) 

Better yet, make sure that the push() methods have a consistent argument argument, but if you cannot do this, use try...except .

+2
source

try below code snippets,

 def push(item, priority=None): print item,priority args = (1,) push(*args) args = (1,2) push(*args) 
+1
source

Can you use the default argument value?

 >>> def foo(a, b = 10): ... print a, b ... >>> foo(1000) 1000 10 >>> foo(1000, 1000) 1000 1000 >>> 

If b not specified, it defaults to 10 .

0
source

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


All Articles