如何检查python中至少有一个指定函数的默认参数

时间:2016-08-10 19:22:49

标签: python function parameter-passing

python中检查是否至少指定了该函数的一个默认参数的最佳做法是什么?

假设我们有一些功能:

def some_function(arg_a=None, arg_b=None, arg_c=False)

带有一些默认参数。就我而言,我需要检查是否指定了arg_aarg_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方法是什么?

5 个答案:

答案 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_aarg_b的预期值,但这通常就足够了。

if not arg_a and not arg_b:
    raise ValueError(...)

假设arg_aarg_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)

  

检查是否至少有一个函数的默认参数   指定的

使用localsdict.valuesany函数的解决方案:

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

https://docs.python.org/2/library/functions.html#any

答案 4 :(得分:0)

由于您正在提议这样一种模式,所以arg_aarg_barg_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。但是它将由类型检查器拾取。