我有一个看起来像这样的函数:
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
之类的东西来处理所需的函数仍然是一种不好的做法吗?
此外,如果这不是一个好的做法,那么这样做的正确方法是什么? 感谢。
答案 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']