Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么“如果没有.”eq“a”看起来是正确的(但不是完全正确的)?_Python_Python 3.x_String_Boolean Expression_Equivalence - Fatal编程技术网

Python 为什么“如果没有.”eq“a”看起来是正确的(但不是完全正确的)?

Python 为什么“如果没有.”eq“a”看起来是正确的(但不是完全正确的)?,python,python-3.x,string,boolean-expression,equivalence,Python,Python 3.x,String,Boolean Expression,Equivalence,如果在Python 3.7中执行以下语句,它将(根据我的测试)打印b: if None.__eq__("a"): print("b") 但是,None.\uuuu eq\uuu(“a”)的计算结果为NotImplemented 自然地,“a”和“a”的计算结果分别为True和“b”。“a”和的计算结果分别为False和 我最初在测试函数的返回值时发现了这一点,但在第二种情况下没有返回任何内容——因此,函数返回了None 这里发生了什么?这是一个很好的例子,说明了为什么不应该直接使用\u

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

if None.__eq__("a"):
    print("b")
但是,
None.\uuuu eq\uuu(“a”)
的计算结果为
NotImplemented

自然地,
“a”和
“a”的计算结果分别为
True和
“b”。
“a”和
的计算结果分别为
False和

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


这里发生了什么?

这是一个很好的例子,说明了为什么不应该直接使用
\uu dunder\uuu
方法,因为它们通常不适合替换其等效运算符;您应该使用
==
运算符进行相等比较,或者在这种特殊情况下,在检查
时,使用
is
(有关详细信息,请跳到答案的底部)

你完成了

None.__eq__('a')
# NotImplemented
由于所比较的类型不同,因此返回
NotImplemented
。请考虑另一个示例,其中两种不同类型的对象正在以这种方式进行比较,例如<代码> 1 和<代码>“A”/代码>。执行
(1)。\uuuu eq\uuuu('a')
也不正确,将返回
未执行
。比较这两个值是否相等的正确方法是

1 == 'a'
# False
这里发生的是

  • 首先,
    (1)。\uuuu eq\uuuu('a')
    被尝试,它返回
    未实现
    。这表示不支持该操作,因此
  • 'a.\uuuu eq\uuuu(1)
    被调用,它还返回相同的
    未实现的
    。所以
  • 对象被视为不相同,并返回
    False
  • 下面是一个很好的小MCVE,它使用一些自定义类来说明这是如何发生的:

    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
    实际上是一个真实值:

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

    bool(NotImplemented)
    # True
    
    有关哪些值被视为truthy和falsy的更多信息,请参阅上的文档部分,以及。这里值得注意的是,
    NotImplemented
    是真实的,但是如果类分别定义了返回
    False
    0
    len
    方法,情况就不同了


    如果需要与
    =
    运算符等效的功能,请使用:

    但是,如前所述,对于此特定场景,如果要检查
    None
    ,请使用
    is

    var = 'a'
    var is None
    # False
    
    var2 = None
    var2 is None
    # True
    
    其功能等效于使用:

    None
    是一个特殊的对象,在任何时候内存中只存在一个版本。照此,它是
    NoneType
    类的唯一单例(但同一个对象可以有任意数量的引用)。委员会明确指出:

    与诸如
    None
    之类的单例进行比较时,应始终使用
    is
    不是
    ,决不是相等运算符


    总之,对于像
    None
    这样的单例,使用
    is
    进行参考检查更合适,尽管
    =
    is
    都可以正常工作。

    您看到的结果是由以下事实造成的:

    None.__eq__("a") # evaluates to NotImplemented
    
    计算结果为
    NotImplemented
    ,并且
    NotImplemented
    的真值记录为
    True

    应通过二进制特殊方法返回的特殊值(例如,
    \uuuuu eq\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
    \uuuuuuuuuuuuuuuuuuuuuuuuu;可通过就地二进制特殊方法返回(例如,
    \uu imul\uu()
    \uuu iand\uuu()
    等),用于相同目的其真值为真。


    如果手动调用
    \uuu eq()\uuuu
    方法,而不是仅使用
    =
    ,则需要准备好处理它可能返回
    NotImplemented
    且其真值为真的可能性

    正如您已经计算出的
    无。
    的计算结果为
    未实现

    if NotImplemented:
        print("Yes")
    else:
        print("No")
    
    结果是

    这意味着
    NotImplemented
    true

    因此,问题的结果是显而易见的:

    None.\uuuu eq\uuuu(某物)
    产生
    NotImplemented

    bool(未实现)
    的计算结果为True

    所以,如果没有,那么
    。\uuuueq\uuuu(“a”)
    总是正确的

    为什么? 它返回一个
    未实现的
    ,耶:

    >>> None.__eq__('a')
    NotImplemented
    >>> 
    
    但如果你看看这个:

    >>> bool(NotImplemented)
    True
    >>> 
    
    NotImplemented
    实际上是一个真实值,因此它返回
    b
    ,任何
    True
    都将通过,任何
    False
    都不会通过

    如何解决? 您必须检查它是否为
    ,因此请更加怀疑,如您所见:

    >>> NotImplemented == True
    False
    >>> 
    
    所以你会这样做:

    >>> if None.__eq__('a') == True:
        print('b')
    
    
    >>> 
    

    正如你所看到的,它不会返回任何东西。

    最直观的答案-值得添加-谢谢:)“值得添加”并没有完全抓住我想说的话(正如你所看到的)-也许“迟来的卓越”是我想要的-cheers@scharfmn对我很想知道你认为这个答案增加了哪些以前没有涉及过的内容。不知何故,这里的视觉/回复功能增加了清晰度-完整性demo@scharfmn ... 虽然提示已被删除,但已接受的答案也已被删除。您是否仅仅因为终端提示被懒散地保留在屏幕上而进行了投票?
    >>> NotImplemented == True
    False
    >>> 
    
    >>> if None.__eq__('a') == True:
        print('b')
    
    
    >>>