The*_*ect 145 python string boolean-expression equivalence python-3.x
如果你在Python 3.7中执行以下语句,它将(从我的测试)打印b
:
if None.__eq__("a"):
print("b")
Run Code Online (Sandbox Code Playgroud)
但是,None.__eq__("a")
评估为NotImplemented
.
当然,"a".__eq__("a")
评估True
和"b".__eq__("a")
评估False
.
我最初在测试函数的返回值时发现了这个,但在第二种情况下没有返回任何内容 - 因此,函数返回了None
.
这里发生了什么?
cs9*_*s95 176
这是为什么__dunder__
不应该直接使用这些方法的一个很好的例子,因为它们通常不适合替代它们的等效运算符; 您应该使用==
运算符进行相等比较,或者在此特殊情况下,在检查时None
使用is
(跳到答案的底部以获取更多信息).
你做完了
None.__eq__('a')
# NotImplemented
Run Code Online (Sandbox Code Playgroud)
NotImplemented
由于被比较的类型不同,因此返回.考虑另一个例子,其中以这种方式比较具有不同类型的两个对象,例如1
和'a'
.做(1).__eq__('a')
也不正确,并将返回NotImplemented
.将这两个值进行比较的正确方法是
1 == 'a'
# False
Run Code Online (Sandbox Code Playgroud)
这里发生的是
(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
Run Code Online (Sandbox Code Playgroud)
当然,这并不能解释为什么操作返回true.这是因为NotImplemented
实际上是一个真正的价值:
bool(None.__eq__("a"))
# True
Run Code Online (Sandbox Code Playgroud)
与...一样,
bool(NotImplemented)
# True
Run Code Online (Sandbox Code Playgroud)
有关哪些值被视为真实和虚假的更多信息,请参阅真值测试的文档部分以及此答案.值得注意的是,这里NotImplemented
是truthy,但它会是一个不同的故事有类中定义的__bool__
或__len__
该方法返回的False
或0
分别.
如果您想要与==
运算符等效的功能,请使用operator.eq
:
import operator
operator.eq(1, 'a')
# False
Run Code Online (Sandbox Code Playgroud)
但是,如前所述,对于您要检查的特定方案,请None
使用is
:
var = 'a'
var is None
# False
var2 = None
var2 is None
# True
Run Code Online (Sandbox Code Playgroud)
功能等同于使用operator.is_
:
operator.is_(var2, None)
# True
Run Code Online (Sandbox Code Playgroud)
None
是一个特殊的对象,任何时候内存中只有1个版本.IOW,它是NoneType
该类的唯一单例(但同一个对象可能有任意数量的引用).该PEP8方针更加明确:
与单身人士的比较
None
应始终使用is
或者is not
从不使用相等运算符.
总之,对于喜欢单身None
,与基准检查is
是比较合适的,虽然两者==
并is
会工作得很好.
Mar*_*yer 33
你看到的结果是由那个事实引起的
None.__eq__("a") # evaluates to NotImplemented
Run Code Online (Sandbox Code Playgroud)
评估为NotImplemented
,并将NotImplemented
真实值记录为True
:
https://docs.python.org/3/library/constants.html
二进制特殊方法应返回的特殊值(例如eq(),lt(),add(),rsub()等),表示该操作未针对其他类型实现; 可以由就地二进制特殊方法(例如imul(),iand()等)返回,用于相同的目的.它的真实价值是真实的.
如果您__eq__()
手动调用方法而不是仅使用__lt__()
,则需要准备好处理它可能返回的可能性__add__()
以及其真值是真的.
Kan*_*jiu 16
正如你已经想通None.__eq__("a")
计算结果为NotImplemented
但是如果你尝试类似
if NotImplemented:
print("Yes")
else:
print("No")
Run Code Online (Sandbox Code Playgroud)
结果是
是
这意味着真相的价值 NotImplemented
true
因此,问题的结果是显而易见的:
None.__eq__(something)
产量 NotImplemented
并bool(NotImplemented)
评估为True
if None.__eq__("a")
总是如此
归档时间: |
|
查看次数: |
4652 次 |
最近记录: |