Python- 在函数定义中为必需参数使用默认值是不正确的吗?

4 投票
2 回答
1363 浏览
提问于 2025-04-17 21:44

我有一个函数,长得像这样:

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 这三个参数在函数中都是必须的。我在调用这个函数时,最多只能传入三个位置参数。我可以选择把它们作为单独的关键字参数传入,并给它们设置默认值为 None,就像我上面展示的那样,或者我也可以用 **kwargs,这样可以接受一个参数字典。

因为我需要检查每个参数是否有值,如果没有就抛出一个 ValueError。那么在定义函数时,给这些必需的参数设置这样的默认值是否不太合适呢?我明白可变默认值的问题,具体可以参考这里 Python中的默认参数值。但是,使用一个哨兵对象或者像 None 这样的值作为必需参数的默认值,还是不好的做法吗?

如果这不是一个好做法,那正确的做法应该是什么呢?谢谢。

2 个回答

1

在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']
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

撰写回答