python中检查是否至少指定了该函数的一个默认参数的最佳做法是什么?
假设我们有一些功能:
def some_function(arg_a=None, arg_b=None, arg_c=False)
带有一些默认参数。就我而言,我需要检查是否指定了arg_a
或arg_b
。所以我想实现这样的东西:
def some_function(arg_a=None, arg_b=None, arg_c=False):
...
if arg_a is not None:
...
elif arg_b is not None:
...
else:
raise ValueError('Expected either arg_a or arg_b args')
...
...
那么,实现这种功能的更多pythonic方法是什么?
答案 0 :(得分:6)
您可以使用all
检查它们是否均等None
并提升ValueError
:
if all(v is None for v in {arg_a, arg_b}):
raise ValueError('Expected either arg_a or arg_b args')
这摆脱了那些if-elif
条款并将所有支票放在同一个地方:
f(arg_a=0) # ok
f(arg_b=0) # ok
f() # Value Error
或者,使用any()
:
if not any(v is not None for v in {arg_a, arg_b}):
raise ValueError('Expected either arg_a or arg_b args')
但这肯定更加模糊。
最后,它实际上取决于pythonic的解释实际上是什么。
答案 1 :(得分:4)
取决于您对arg_a
和arg_b
的预期值,但这通常就足够了。
if not arg_a and not arg_b:
raise ValueError(...)
假设arg_a
和arg_b
不是布尔值,并且不能将零,空字符串/列表/元组等作为参数。
根据您的需要,如果您需要区分“无”和“假”,您可以更加精确。例如False,0,"",[],{},()等:
if arg_a is None and arg_b is None:
raise ValueError(...)
答案 2 :(得分:1)
如果你的不匹配默认值有很多这样的命名参数,你可以考虑使用def some_function(**kwargs):
reqd = ['arg_a', 'arg_b']
if not all(i in kwargs for i in reqd):
raise ValueError('Expected either {} args'.format(' or '.join(reqd)))
arg_a = kwargs.get('args_a')
arg_b = kwargs.get('args_b')
arg_c = kwargs.get('args_c', False)
:
import React, { Component } from 'react';
class Navigation extends Component {
getLinks = (object) => {
Object.keys(object).map((property, i) => {
const { text, title } = object[property][i];
console.log(object[property][i])
return (
<ul>{title}
<li>{text}</li>
</ul>
)
});
}
render() {
let { items } = this.props;
return (
<div>
<ul>
{this.getLinks(items)}
</ul>
</div>
);
}
}
export default Navigation;
答案 3 :(得分:0)
检查是否至少有一个函数的默认参数 指定的
使用locals
,dict.values
和any
函数的解决方案:
def some_function(arg_a=None, arg_b=None, arg_c=False):
args = locals()
if (any(args.values()) == True):
print('Ok')
else:
raise ValueError('At least one default param should be passed!')
some_function(False, 1) # Ok
some_function('text', False, None) # Ok
some_function(0, False, None) # Error
答案 4 :(得分:0)
由于您正在提议这样一种模式,所以arg_a
,arg_b
和arg_c
可能有一些统一的含义。如果是这样,您可以...
from enum import Enum
class Group(Enum):
A = auto()
B = auto()
C = auto()
def some_function(val: int, t: Group):
if t == Group.A:
# do stuff with val
elif t == Group.B:
# do other stuff with val
elif t == Group.C:
# do other stuff with val
some_function(1, Group.A)
在此,调用方必须指定一个值以及该值对应的内容。围绕python中缺少适当的枚举支持,这有点可笑,我不知道它是否是pythonic。但是它将由类型检查器拾取。