As an example I have a function f
and a variable a=1
. Sometimes f
needs a
and I want to call f(a=a)
and other times f
has no arguments. How can I deal with that?
When I try to call f(a=a)
(expecting that it will silently ignore the case where a
is not used in f
), I get the following TypeError:
f got an unexpected keyword argument 'a'
Edit
I want to implement a function g
such that, given:
def f1(a):
return a
def f2():
return 1
we have:
g(f1, a) == a
g(f2, a) == 1
use keyword dictionary in f
:
def f(**kwargs):
if 'a' in kwargs:
print("a passed with value {}".format(kwargs['a']))
else:
print('a not passed')
f(a=12)
f()
prints:
a passed with value 12
a not passed
it makes argument testing/retrieving completely manual. You can do anything you want, and it can be generalized to several arguments.
This also forbids to pass arguments as positional like f(12)
which is probably a good thing in your case.
>>> f(12)
Traceback (most recent call last):
TypeError: f() takes 0 positional arguments but 1 was given
The drawback is that the caller cannot rely on parameter names to know what to pass. Either create a docstring, or people will have to read the code/guess...
Now to apply that to your edit, which kind of changes the problem I must say. So f2
cannot be changed, in that cas the work must be done in the wrapper function:
def f1(a):
return a
def f2():
return 1
def g(f,arg):
try:
return f(a=arg)
except TypeError:
return f()
a=12
print(g(f1, a))
print(g(f2, a))
prints:
12
1
so "better ask forgiveness than permission": if we get a TypeError
(raised when the parameter isn't known by the function), we just call the function without the parameter. The drawback if that if the first function returns a TypeError
, we cannot know if it was the parameters or inside the function.
A workaround would be to inspect the error message and only call the function without parameters if the error message is about parameters:
def g(f,arg):
try:
return f(a=arg)
except TypeError as e:
if "unexpected keyword" in str(e):
return f()
else:
raise e # another TypeError, let it pass
It seems you want to inspect a function's arguments.
For that, use the inspect
module:
import inspect
def g(somefunc, *params):
num_args = len(inspect.getargspec(somefunc).args)
return somefunc(*params[:num_args])
Testing, with your functions:
def f1(a):
return a
def f2():
return 1
>>> print(g(f1, 3))
3
>>> print(g(f2, 3))
1
Simply specify the default argument in the function def
line...
def f(a=1):
return(a)
print(f()) #returns 1
print(f(a = 2)) #returns 2
For your next part (as you seemed to have switched your question with edits...
def g(f, a):
return(f(a))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.