为什么 `if None.

编程入门 行业动态 更新时间:2024-10-24 20:18:36
本文介绍了为什么 `if None.__eq__("a")` 似乎评估为 True(但不完全是)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

如果您在 Python 3.7 中执行以下语句,它将(根据我的测试)打印 b:

If you execute the following statement in Python 3.7, it will (from my testing) print b:

if None.__eq__("a"): print("b")

但是,None.__eq__("a") 的计算结果为 NotImplemented.

However, None.__eq__("a") evaluates to NotImplemented.

自然,"a".__eq__("a") 的计算结果为 True,而 "b".__eq__("a")> 计算结果为 False.

Naturally, "a".__eq__("a") evaluates to True, and "b".__eq__("a") evaluates to False.

我最初在测试函数的返回值时发现了这一点,但在第二种情况下没有返回任何内容——因此,该函数返回了 None.

I initially discovered this when testing the return value of a function, but didn't return anything in the second case -- so, the function returned None.

这是怎么回事?

推荐答案

这是一个很好的例子,说明为什么 __dunder__ 方法不应该直接使用,因为它们通常不适合替代它们的等效方法运营商;您应该使用 == 运算符代替相等比较,或者在这种特殊情况下,在检查 None 时,使用 is(跳到答案底部以获取更多信息).

This is a great example of why the __dunder__ methods should not be used directly as they are quite often not appropriate replacements for their equivalent operators; you should use the == operator instead for equality comparisons, or in this special case, when checking for None, use is (skip to the bottom of the answer for more information).

你已经完成了

None.__eq__('a') # NotImplemented

返回 NotImplemented 因为被比较的类型不同.考虑另一个示例,其中以这种方式比较具有不同类型的两个对象,例如 1 和 'a'.做 (1).__eq__('a') 也是不正确的,会返回 NotImplemented.比较这两个值是否相等的正确方法是

Which returns NotImplemented since the types being compared are different. Consider another example where two objects with different types are being compared in this fashion, such as 1 and 'a'. Doing (1).__eq__('a') is also not correct, and will return NotImplemented. The right way to compare these two values for equality would be

1 == 'a' # False

这里发生了什么

  • 首先,尝试(1).__eq__('a'),它返回NotImplemented.这表示不支持该操作,所以
  • 'a'.__eq__(1) 被调用,它也返回相同的 NotImplemented.所以,
  • 对象被视为不相同,并返回False.
  • First, (1).__eq__('a') is tried, which returns NotImplemented. This indicates that the operation is not supported, so
  • 'a'.__eq__(1) is called, which also returns the same NotImplemented. So,
  • The objects are treated as if they are not the same, and False is returned.
  • 这是一个不错的小 MCVE,使用一些自定义类来说明这是如何发生的:

    Here's a nice little MCVE using some custom classes to illustrate how this happens:

    class A: def __eq__(self, other): print('A.__eq__') return NotImplemented class B: def __eq__(self, other): print('B.__eq__') return NotImplemented class C: def __eq__(self, other): print('C.__eq__') return True a = A() b = B() c = C() print(a == b) # A.__eq__ # B.__eq__ # False print(a == c) # A.__eq__ # C.__eq__ # True print(c == a) # C.__eq__ # True

    当然,这并不能解释为什么操作返回 true.这是因为 NotImplemented 实际上是一个真值:

    Of course, that doesn't explain why the operation returns true. This is because NotImplemented is actually a truthy value:

    bool(None.__eq__("a")) # True

    同,

    bool(NotImplemented) # True

    有关哪些值被视为真值和假值的更多信息,请参阅 真值测试,以及这个答案.这里值得注意的是 NotImplemented 是真实的,但如果该类定义了一个 __bool__ 或 __len__ 方法返回False 或 0 分别.

    For more information on what values are considered truthy and falsy, see the docs section on Truth Value Testing, as well as this answer. It is worth noting here that NotImplemented is truthy, but it would have been a different story had the class defined a __bool__ or __len__ method that returned False or 0 respectively.

    如果您需要 == 运算符的等效功能,请使用 operator.eq:

    If you want the functional equivalent of the == operator, use operator.eq:

    import operator operator.eq(1, 'a') # False

    但是,如前所述,对于这个特定场景,您正在检查None,请使用is:

    However, as mentioned earlier, for this specific scenario, where you are checking for None, use is:

    var = 'a' var is None # False var2 = None var2 is None # True

    与此等效的功能是使用 operator.is_:

    The functional equivalent of this is using operator.is_:

    operator.is_(var2, None) # True

    None 是一个特殊的对象,在任何时候内存中都只存在一个版本.IOW,它是 NoneType 类的唯一单例(但同一个对象可能有任意数量的引用).PEP8 指南 明确指出:

    None is a special object, and only 1 version exists in memory at any point of time. IOW, it is the sole singleton of the NoneType class (but the same object may have any number of references). The PEP8 guidelines make this explicit:

    与 None 之类的单例比较应该始终使用 is 或不是,永远不是等号运算符.

    Comparisons to singletons like None should always be done with is or is not, never the equality operators.

    总而言之,对于像 None 这样的单例,使用 is 进行引用检查更合适,尽管 == 和 都是 会工作得很好.

    In summary, for singletons like None, a reference check with is is more appropriate, although both == and is will work just fine.

    更多推荐

    为什么 `if None.

    本文发布于:2023-11-27 08:53:14,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1637373.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!