Python-在函数def中使用所需参数的默认值是否错误?
我有一个func,看起来像这样:Python-在函数def中使用所需参数的默认值是否错误?,python,python-2.7,Python,Python 2.7,我有一个func,看起来像这样: 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、par
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的调用方式,我有最多3个位置的限制。我可以像上面显示的那样,将它们作为默认值为None
的单个关键字参数收集,或者作为**kwargs
收集,它可以接受参数字典
由于我正在检查每个参数是否分配了某些值,或者是否引发了ValueError
,因此在func def期间对所需参数使用此类默认值是否错误。
我理解这里解释的可变默认值的问题。但是对于所需的func参数使用sentinel对象或类似None
的东西仍然是一种糟糕的做法吗
此外,如果这不是一个好的做法,那么什么是正确的做法?
谢谢。在Python 3中,您可以使用必须通过关键字传递的必需变量:
def somefunc(pos1, pos2, *, kwonly3, kwonly4): # kwonly3 and kwonly4 are still required!
pass
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
但我不确定你是否一定需要这个。如果您的函数在所有参数都是位置参数的情况下有意义,您仍然可以通过API调用它,该API通过关键字传递这些参数:
def somefunc(pos1, pos2, *, kwonly3, kwonly4): # kwonly3 and kwonly4 are still required!
pass
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)
:
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']
这并不完全是“错误的”,但如果它们是必需的,为什么不通过省略默认值使它们成为必需的参数呢?您仍然可以将它们作为关键字参数传递(def func(foo,bar)
可以用func(bar=2,foo=1)
调用)。是的,这在逻辑上是错误的(尽管在语法上是正确的)。如果需要这些参数,请让用户通过不指定默认值来提供它们。如果它们不是必需的,为什么要测试它们是否都提供了。如果用默认值调用它们是不正确的,为什么要给它们默认值?我忘了添加一个限制:我只能根据api实际调用func的方式提供3个位置。您使用的是哪一版本的Python?Python3可以使用诸如def somefunc(param1,param2,*,param3,param4)之类的语法,只包含关键字变量:
。*
表示其余参数仅为关键字,因为它们没有默认值,所以是必需的。