【问题标题】:Should I just use `==` to compare to `(None, None)` tuple?我应该只使用 `==` 来比较 `(None, None)` 元组吗?
【发布时间】:2019-08-14 07:41:14
【问题描述】:

我有一个函数,它可以返回两个整数的元组或(None, None) 的元组:

(为了这个问题,我们假设这个返回格式是唯一的方法,并且不能改变)

from typing import Tuple, Union

def foo(n: int) -> Union[Tuple[int, int], Tuple[None, None]]:
    if n < 0:
        return None, None
    return n, n

那我想写一个pytest unittest 来测试这个功能。总是说应该将Noneis 进行比较,但这显然行不通:

def test_foo():
    assert foo(1) == (1, 1)
    assert foo(-1) is (None, None)  # fails obviously!

在这种情况下我应该只使用== 来比较结果吗?

def test_foo():
    assert foo(1) == (1, 1)
    assert foo(-1) == (None, None)  # best way?

【问题讨论】:

  • 您不与None 比较,而是与一个元组(恰好包含None)进行比较。所以与==比较是要走的路。
  • @Matthias 是的,这是我对此的假设,但由于我找不到任何问题,所以我想 a) 确保我的假设是正确的 b) 提供答案也为将来的其他人:)

标签: python tuples nonetype comparison-operators


【解决方案1】:

您应该使用==,但实际上使用is 会失败并不是“显而易见的”。

例如

def foo():
    return (1, 2)

print(foo() is foo())

可能实际上返回 True(在 CPython 中确实如此,不确定其他实现)。

元组不是实体,而是值。不应使用值上的标识,因为它可能匹配或不匹配(例如字符串或数字发生的情况)。

如果在上面的代码中使用[1, 2] 而不是(1, 2),则可以保证is 将返回False,因为列表是实体,而不是值,并且可以以可预测的方式使用标识。

【讨论】:

  • 在 Python 中,元组是对象,因为一切都是对象。但是 Python 混淆了这个问题,因为它没有一个好的术语来表示“通常只按值比较的对象”。
  • @DavidJones:确实......我将术语改为“实体”以避免对象
【解决方案2】:

另一个建议,使用列表推导来检查 is None 的所有返回值:

def test_foo():
    assert foo(1) == (1, 1)
    assert all(i is None for i in foo(-1))

【讨论】:

  • 这可以简化为assert all(i is None for i in foo(-1)) fyi!你不需要列出一个列表,只需使用生成器表达式即可。
猜你喜欢
  • 2020-05-09
  • 1970-01-01
  • 2010-10-31
  • 2018-09-10
  • 2019-08-14
  • 1970-01-01
  • 2021-06-30
  • 2012-10-25
  • 1970-01-01
相关资源
最近更新 更多