python 非 None 默认值
程序员A写了一个函数:
def compute_value(threshold = sys.float_info.max):
...
return value
这个函数有一个可选参数threshold,默认值是一个很大的浮点数,表示“没有阈值”。
程序员B也有一个阈值的表示方法,但他用None来表示没有阈值。不幸的是,当threshold为None时,compute_value函数不会抛出任何异常,但会给出错误的答案。因此,当程序员B传入None作为阈值时,就出现了一个bug。
我认为最好的解决办法是修改这个函数:
def compute_value(threshold = None):
if threshold is None:
threshold = sys.float_info.max
...
return value
因为这个函数比之前更通用,它以一种合理的方式处理None值。
这就引出了一个问题:是否总是最好只使用None作为默认值?
这并不是我第一次遇到默认参数不是None而导致麻烦的情况。在其他情况下,我发现自己需要从kwargs字典中移除None值……
还有一个相关的(可能有点傻)问题。实际上,程序员B将上面的函数修改成了这样:
def compute_value(threshold = sys.float_info.max):
if threshold is None:
threshold = sys.float_info.max
...
return value
这个修改是完全正确的,但我觉得看起来不太好。不好是因为sys.float_info.max重复了两次……但是:这算不算违反了DRY原则?因为严格来说,在第一个实现中,None也重复了两次,而None和sys.float_info.max都是常量。
2 个回答
你还可以通过使用kwargs来解决None
作为默认值的问题。
def compute_value(**kwargs):
threshold = kwargs.get('threshold', sys.float_info.max)
...
return value
这其实就是在问你(作为API提供者)是否认为None
可以作为一个有效的参数传给这个函数。就我个人而言,在这种情况下,我觉得我会使用sys.float_info.max
,并且不允许使用None
。毕竟,None
为什么要假装成一个float
呢?None作为默认参数的标准用法是当你需要一个可变的默认参数,但在这里并不是这种情况。
不过,也可以反过来说——如果你使用None
,那么help
会告诉你阈值是None
,从“把代码当文本看”的角度来看,这也有点道理。(毕竟,这意味着没有阈值)。1
不过最终,这其实只是斤斤计较罢了。选择一个约定,记录下来并坚持使用。别太担心这个问题。
1如果你有自动生成的文档(比如sphinx),而且sys.float_info.max
在生成文档的电脑上返回的值和运行代码的电脑上不一样,这种情况就更糟糕了。这个场景其实不太可能发生——现在大多数电脑都遵循IEEE标准,但……