Python- 在函数定义中为必需参数使用默认值是不正确的吗?
我有一个函数,长得像这样:
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