
这是一个很好的例子,说明为什么
__dunder__不应该直接使用这些方法,因为它们通常不是等效 *** 作符的适当替代;您应该使用
==运算符来代替相等性比较,或者在这种特殊情况下,当检查时
None,请使用
is(跳至答案的底部以获取更多信息)。
你做完了
None.__eq__('a')# NotImplementedNotImplemented由于要比较的类型不同,返回的结果不同。考虑另一个示例,其中以这种方式比较了具有不同类型的两个对象,例如
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 NotImplementedclass B: def __eq__(self, other): print('B.__eq__') return NotImplementedclass C: def __eq__(self, other): print('C.__eq__') return Truea = A()b = B()c = C()print(a == b)# A.__eq__# B.__eq__# Falseprint(a == c)# A.__eq__# C.__eq__# Trueprint(c == a)# C.__eq__# True当然,这并不能解释 为什么 该 *** 作返回true。这是因为
NotImplemented实际上是一个真实值:
bool(None.__eq__("a"))# True和…一样,
bool(NotImplemented)# True
有关什么值被认为是真实和虚假的更多信息,请参阅真值测试的文档部分以及此答案。值得注意的是,这里
NotImplemented是truthy,但它会是一个不同的故事有类中定义一个
__bool__或
__len__方法返回
False或
0分别。
如果要
==使用与运算符等效的功能,请使用
operator.eq:
import operatoroperator.eq(1, 'a')# False
但是,如前所述,对于要检查的 特定情况 ,请
None使用
is:
var = 'a'var is None# Falsevar2 = Nonevar2 is None# True
其功能等效项是使用
operator.is_:
operator.is_(var2, None)# True
None是一个特殊对象,并且在任何时间内存中只有1个版本。IOW,它是类的唯一单例
NoneType(但是同一对象可以具有任意数量的引用)。该PEP8方针更加明确:
与单例之类的比较
None应始终使用is或is not,而不应使用相等运算符。
综上所述,对于单身人士喜欢
None,与基准检查
is是比较合适的,虽然两者
==并
is会工作得很好。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)