如果您在Python 3.7中执行以下语句,它将(根据我的测试)打印b
:
if None.__eq__("a"):
print("b")
但是,None.__eq__("a")
计算结果为NotImplemented
。
当然,"a".__eq__("a")
计算结果为True
,并"b".__eq__("a")
计算结果为False
。
我最初是在测试函数的返回值时发现此问题的,但是在第二种情况下却未返回任何内容-因此,该函数返回了None
。
这里发生了什么?
这是一个很好的例子,说明为什么__dunder__
不应该直接使用这些方法,因为它们通常不是等效操作符的适当替代;您应该使用==
运算符来代替相等性比较,或者在这种特殊情况下,当检查时None
,请使用is
(跳至答案的底部以获取更多信息)。
你做完了
None.__eq__('a')
# NotImplemented
NotImplemented
由于要比较的类型不同,返回的结果不同。考虑另一个示例,其中以这种方式比较了具有不同类型的两个对象,例如1
和'a'
。这样做(1).__eq__('a')
也不正确,并且会返回NotImplemented
。比较这两个值是否相等的正确方法是
1 == 'a'
# False
这里发生的是
(1).__eq__('a')
尝试,然后返回NotImplemented
。这表明不支持该操作,因此'a'.__eq__(1)
被调用,它也返回相同的NotImplemented
。所以,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
有关什么值被认为是真实和虚假的更多信息,请参阅真值测试的文档部分以及此答案。值得注意的是,这里NotImplemented
是truthy,但它会是一个不同的故事有类中定义一个__bool__
或__len__
方法返回False
或0
分别。
如果要==
使用与运算符等效的功能,请使用operator.eq
:
import operator
operator.eq(1, 'a')
# False
但是,如前所述,对于要检查的 特定情况 ,请None
使用is
:
var = 'a'
var is None
# False
var2 = None
var2 is None
# True
其功能等效项是使用operator.is_
:
operator.is_(var2, None)
# True
None
是一个特殊对象,并且在任何时间内存中只有1个版本。IOW,它是类的唯一单例NoneType
(但是同一对象可以具有任意数量的引用)。该PEP8方针更加明确:
与单例之类的比较
None
应始终使用is
或is not
,而不应使用相等运算符。
综上所述,对于单身人士喜欢None
,与基准检查is
是比较合适的,虽然两者==
并is
会工作得很好。
问题内容: 对于我确定的人来说,这是一个简单的答案。有人可以解释为什么此表达式的值为真吗? 问题答案: 因为您使用的是==(相似性)运算符,而PHP将字符串强制为int。 要解决此问题,请使用===(等于)运算符,该运算符不仅会检查值是否相同,还会检查数据类型是否相同,因此“ 123”字符串和123 int不会被视为相等。
问题内容: 为什么用Python生成? 我在这里阅读以下内容: 如果两个字符串文字相等,则将它们放在相同的内存位置。字符串是不可变的实体。不会造成伤害。 那么每个Python字符串在内存中只有一个位置吗?听起来很奇怪。这里发生了什么? 问题答案: Python(例如Java,C,C ++ 、. NET)使用字符串池/内联。解释器意识到“ hello”与“ hello”相同,因此它优化并使用了内存中
问题内容: 给出以下代码: 为什么会这样?我以为布尔值会被强制转换为数字。因此变得和变。第二条if语句很有意义,但是我不明白为什么第一条语句导致要评估内部循环。这里发生了什么? 问题答案: 它被强制转换为布尔值。任何非空字符串的求值为true。 根据[ECMAScript语言规范]: ## 12.5 声明 ### 语义学 生产 IfStatement : Expression Statement
问题内容: 我正在使用JDBC连接到MySQL服务器(我认为没有连接池)。在连接网址中,我有 但是我的连接仍然超时。我什至检查了它的错误。但是,当我尝试使用连接时,出现以下异常。 我知道在Java 1.6中可以使用它来检查连接,但是我正在使用Java 1.5 有没有办法确保它不会超时?还是我必须升级到Java 1.6? 问题答案: 我有同样的问题,这绝对令人发疯。这是文档在MySQL网站上的内容(
问题内容: 我真的不明白这是如何解析的。为什么第二个示例返回False? 谢谢你的帮助。我想我一定会错过一些非常明显的东西。 我认为这与链接重复项有细微不同: 为什么表达式0 <0 == 0在Python中返回False? 。 这两个问题都与人类对表达的理解有关。在我看来,似乎有两种评估表达方式的方法。当然,两者都不正确,但是在我的示例中,最后的解释是不可能的。 看着您可以想象每个被评估的部分都可
问题内容: 我遇到了这个表达式,我认为应该评估为True,但事实并非如此。 上面的语句按预期工作,但在以下情况下: 执行后,其结果为False。 我尝试搜索答案,但无法获得具体答案。谁能帮助我了解这种行为? 问题答案: 是一个运营商链,就像您 要做到这一点,您需要 和 都是如此。后者是错误的,因此是结果。添加括号不会再使运算符链接(某些运算符在括号中),这可以解释工作原理。 尝试: 再一次,一个很