【问题标题】:python non None default valuespython非无默认值
【发布时间】:2014-07-03 11:41:31
【问题描述】:

程序员A写了如下函数:

def compute_value(threshold = sys.float_info.max):
   ...
   return value

它具有可选参数threshold,它以自然的方式具有最大浮点值作为默认值来表示“无阈值”。

程序员 B 也有一个阈值的表示,但使用 None 表示没有阈值。不幸的是,如果 threshold=None,compute_value 函数不会引发任何异常,但会给出错误的答案。因此,当程序员 B 通过 None 作为阈值时会出现错误。

我会说最好的解决方案是改变功能

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 都是常量。

【问题讨论】:

  • 变量 sys.float_info.max 可以通过从 sys 模块在脚本中导入来访问,所以我不明白为什么要将其值传递给参数
  • “不幸的是,如果 threshold=None,compute_value 函数不会引发任何异常,但会给出不正确的答案”——我很难想出一个你 不会 如果您有 None 并将其用作 float,则会出现异常... @,但如果这是您使用名为 threshold 的变量的唯一方法,那将是一个非常小的角落......
  • @mgilson 只是在这里吹毛求疵,但if x: 在检查 None 和浮点数时并不是明智之举,因为 x=0 也会触发条件。
  • 为了讲述整个故事,我实际上正在使用 pandas.DataFrame.between(min_value,max_value) (由于某些原因我不知道)接受 None 但威胁它作为 -INF 值。而且我没有使用 sys.float_info.max 而是 numpy.finfo(float).max
  • @Dhara -- 这正是我的观点。我想不出有什么好的用途,只有一个不好的用途是None 可以伪装成float 而不会引发异常。

标签: python default-value


【解决方案1】:

您还可以使用 kwargs 解决 None 默认值

def compute_value(**kwargs):
    threshold = kwargs.get('threshold', sys.float_info.max)
    ...
    return value

【讨论】:

  • 在我看来,这种方法并不能解决问题。如果我将 threshold=None 传递给您的函数,它在 kwargs.get(...) 之后仍然是 threshold=None
  • 是的,它不处理 None 值,它只允许将默认 None 值与显式传递的 None 值区分开来。至于我,我同意@mgilson 的观点,即明确传递None 是个坏主意,最好根本不提供args,而不是将None 作为“最大浮点数”传递。
【解决方案2】:

这真的归结为您(API 提供者)是否认为None 应该是传递给函数的有效参数。就个人而言,在这种情况下,我想我会使用sys.float_info.max 并禁止使用None。毕竟,None 为什么要伪装成floatcanonical 使用 None 作为默认参数是当您需要一个可变 默认参数时,但这里不是这种情况。

有一个相反的论据——如果你使用None,那么help会告诉你阈值是None,从“将代码读取为文本”的角度来看这是有道理的. (毕竟你的意思是没有门槛)。1

但最终,这主要是在这一点上分裂头发。选择一个约定,记录它并坚持下去。不用太担心。


1如果您有自动生成的文档(例如 sphinx)并且sys.float_info.max 在生成文档的计算机上返回的值与运行代码的计算机。这种情况不太可能发生——如今大多数计算机都同意 IEEE,但是 ...

【讨论】:

  • 即使我是程序员 A(最初按照您的建议编写代码),我也不同意您的(第一个)动机。我认为默认为 None 的界面更加清晰。 sys.float_info.max 值在我看来是一个实现细节......无论如何,既然我已经征求意见,我会接受更多投票的答案......
猜你喜欢
  • 2012-08-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 2020-09-04
相关资源
最近更新 更多