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

Python- Is it wrong to use default values for required parameters in function def?

我有一个类似这样的功能:

1
2
3
4
5
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"

param3, param4, param5均为func所需。根据如何调用func,最多有3个位置限制。我可以像上面显示的那样,将它们作为默认值为None的单个关键字参数收集起来,或者作为可以接受参数字典的**kwargs收集起来。

因为我正在检查每个参数是否分配了一些值,或者引发一个ValueError,所以在func def期间对所需参数使用这样的默认值是错误的。我了解使用可变默认值的问题,正如这里在python中解释的默认参数值。但是,使用哨兵对象或类似于None的东西作为必需的func参数仍然是一种坏做法吗?

另外,如果这不是一个好的实践,那么什么样的方法才是正确的呢?谢谢。


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

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

但我不确定你一定需要这个。如果函数的所有参数都是位置的,那么仍然可以通过通过通过关键字传递这些参数的API来调用它:

1
2
3
4
5
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

在python中,向函数传递错误数量的参数是TypeError。在您的情况下,传递错误值(如None)可能是ValueError

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

1
2
3
4
5
6
7
8
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']