我有一个带有两个可选参数的函数:
def func(a=0, b=10):
return a+b
我的代码中的其他地方我正在做一些条件参数传递,如:
if a and b:
return func(a, b)
elif a:
return func(a)
elif b:
return func(b=b)
else:
return func()
无论如何都要简化这种模式中的代码吗?
修改:
我们假设 不允许在func
内实现默认参数逻辑。
我可能有多个功能,例如func
:func1
,func2
和func3
都会包含
a = a or 0
b = b or 10
语句。
但是我正在调用这些系列函数来消除重复。 (使用装饰器)
答案 0 :(得分:20)
如果你不想改变func
中的任何内容,那么明智的选择就是将一个参数的dict传递给函数:
>>> def func(a=0,b=10):
... return a+b
...
>>> args = {'a':15,'b':15}
>>> func(**args)
30
>>> args={'a':15}
>>> func(**args)
25
>>> args={'b':6}
>>> func(**args)
6
>>> args = {}
>>> func(**args)
10
或只是:
>>>func(**{'a':7})
17
答案 1 :(得分:1)
为什么不将该逻辑传递给函数?
def func(a, b):
a = a or 0
b = b or 10
return a + b
答案 2 :(得分:1)
解决您的具体问题:
args = {'a' : a, 'b' : b}
for varName, varVal in args.items():
if not varVal:
del args[varName]
f(**args)
但最pythonic的方法是使用None作为函数的默认值:
f(a=None, b=None):
a = 10 if a is None else a
...
然后致电f(a, b)
答案 3 :(得分:1)
通过现在删除的注释来查看检查对于变量None
而不是假的问题,更改func
以便它处理参数{{1 }}:
None
然后每次只调用def func(a=None, b=None):
if a is None:
a = 0
if b is None:
b = 10
。
答案 4 :(得分:1)
默认情况下,Python中的所有方法都采用variable arguments。
当您在方法的签名中定义参数时,您明确地要求它。在你的代码片段中,你正在做的是给它一个默认值 - 而不是让它们成为可选的。
请考虑以下事项:
>>> def func(a,b):
... a = a if a else 0
... b = b if b else 10
... return a+b
...
>>> a = b = None
>>> func(a,b)
10
>>> a = 5
>>> b = 2
>>> func(a,b)
7
>>> func()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() takes exactly 2 arguments (0 given)
在此代码段中,a
和b
都是必需,因为我没有定义任何默认值。它们不是可选。
但是在你的代码片段中,因为你已经在方法签名中给出了默认值,它们看起来像它们是可选的,但实际上它们只是分配了默认值。
>>> def func(a=0,b=10):
... return a+b
...
>>> func()
10
您可以通过检查方法正文中的参数列表来确认:
>>> def func(a=b,b=10):
... print locals().keys()
...
>>> func()
['a', 'b']
让你的函数接受任何个参数的一种方法(换句话说,使它们都是可选的):
>>> def func(*args,**kwargs):
... print len(args),args
... print len(kwargs),kwargs
...
>>> func("hello","world",a=5,b=10)
2 ('hello', 'world')
2 {'a': 5, 'b': 10}
>>> func()
0 ()
0 {}
>>> func(1,2)
2 (1, 2)
0 {}
>>> func(a)
1 (5,)
0 {}
>>> func(foo="hello")
0 ()
1 {'foo': 'hello'}
答案 5 :(得分:1)
您可以添加一个可以消除None
个参数的装饰器:
def skip_nones(fun):
def _(*args, **kwargs):
for a, v in zip(fun.__code__.co_varnames, args):
if v is not None:
kwargs[a] = v
return fun(**kwargs)
return _
@skip_nones
def func(a=10, b=20):
print a, b
func(None, None) # 10 20
func(11, None) # 11 20
func(None, 33) # 10 33
答案 6 :(得分:0)
回答你的字面问题:
func(a or 0, b or 10)
修改强> 请参阅评论为什么这不能回答这个问题。
答案 7 :(得分:0)
这可能有效:
def f(**kwargs):
a = get(kwargs, 0)
b = get(kwargs, 10)
return a + b
答案 8 :(得分:0)
您可以使用三元if-then运算符将条件论证传递给函数 https://www.geeksforgeeks.org/ternary-operator-in-python/
例如,如果要在传递密钥之前检查密钥是否确实存在,可以执行以下操作:
spreadsheet