Python-在函数def中使用必需参数的默认值是错误的吗?

时间:2014-03-11 04:56:13

标签: python python-2.7

我有一个看起来像这样的函数:

def somefunc(param1, param2, param3=None, param4=None, param5=None):
    if not all([param3, param4, param5]):
        raise ValueError("Invalid Parameters")

    #continue with rest of the logic if no "ValueError"
func需要

param3, param4, param5。我根据func的调用方式限制了最多3个位置。我可以将它们作为单独的关键字参数收集,默认值为None,如上所示,或者**kwargs可以接受参数字典。

由于我正在检查每个参数是否分配了某个值,或者是否引发了ValueError,因此在func def期间对所需的参数使用这些默认值是错误的。 我理解了可变默认值的问题,如Default Parameter Values in Python所述。但是使用一个标记对象或类似None之类的东西来处理所需的函数仍然是一种不好的做法吗?

此外,如果这不是一个好的做法,那么这样做的正确方法是什么? 感谢。

2 个答案:

答案 0 :(得分:2)

在Python 3中,您可以拥有必须通过关键字传递的必需变量:

def somefunc(pos1, pos2, *, kwonly3, kwonly4): # kwonly3 and kwonly4 are still required!
    pass

但我不确定你是否一定需要这个。如果您的函数在参数全部是位置的情况下有意义,您仍然可以通过按关键字传递它们的API来调用它:

def somefunc2(pos1, pos2, pos3, pos4): # all parameters are required
    pass

# you can call the function with keyword arguments, or even with **kwargs
somefunc2("foo", "bar", pos3="baz", **{"pos4": "quux"}) # this will work

答案 1 :(得分:0)

在Python中向函数传递错误数量的参数是TypeError。在您的案例中传递错误的值None可能是ValueError

在Python 2中模拟somefunc(param1, param2, *, param3, param4, param5)

def somefunc(param1, param2, **kwargs):
    if somefunc.kwargs != sorted(kwargs):
        raise TypeError('Expected exactly %d keyword-only args: %r; got %r' % (
                        len(somefunc.kwargs), somefunc.kwargs, kwargs))
    if any(v is None for v in kwargs.values()):
        raise ValueError("%s can't be None; got %r" % (
                         ", ".join(somefunc.kwargs), kwargs))
somefunc.kwargs = ['param3', 'param4', 'param5']