将“a == True:”简化为“a”——这是个好主意吗?
Posted
技术标签:
【中文标题】将“a == True:”简化为“a”——这是个好主意吗?【英文标题】:Simplifying "a == True:" to "a" - is it a good idea? 【发布时间】:2021-11-03 20:14:45 【问题描述】:PEP8 建议应简化以下代码。
原版
if a == True:
建议
if a:
但是,这两者并不相同。当我遵循 PEP8 建议时,我发现了这一点。试试下面的代码
import numpy as np
a = np.nan
if a == True:
print('a is True')
else:
print('a is not True')
if a:
print('a is True')
else:
print('a is not True')
你会发现第一个告诉 a 不正确(正确),而第二个错误告诉 a 是真的。
a is not True
a is True
这个误导性建议的意义何在?
【问题讨论】:
如果您正在使用可能值为True
或np.nan
的变量,那么这是您的设计问题,而不是布尔比较。 if
声明检查数据的真实性。您应该始终了解数据的一般形状。如果数据是一个列表,if
会检查它是否为空。如果数据是布尔值,if
会检查它是否为真。 Python 程序员一眼就能看出这些意图。 == True
只是混淆了这一点,并使惯用的 Python 编码人员认为正在发生一些非常可疑的事情。
您的问题是类型不匹配。 a
是布尔值还是数字?您将 nan
分配给它,它具有真实性值。当您说a = np.nan; if a
时,您是在说“a 是否有价值”。 (它确实是 nan 的值。)通常,如果将值分配给未明确为 False、None、0 或空的名称,您可以期望真值评估将其视为“True”。此外,由于您在询问if a == True
时没有指定a = True
,因此您会得到错误的结果。就像你问if 2 == True
一样。 nan
不是 True - 它甚至不是布尔值。
PEP8 建议从根本上假设您了解 Python 的真值测试语义,here is the relevant documentation 在这种情况下,np.nan
是真的。为什么你不这么认为?
非常感谢您的良好反馈。不过,我认为建议用不产生相同结果的东西来简化短语有点问题。
Matti:definition 的“真实性”表明看似真实的品质与逻辑、事实证据等无关。
【参考方案1】:
您误读了 PEP8 风格指南。这是相关部分(强调我的):
不要使用 == 将 boolean 值与 True 或 False 进行比较:
# Correct: if greeting: # Wrong: if greeting == True:
由于np.nan
不是布尔值,因此此建议不适用。
请注意,如果您将数值与True
进行比较,那么您通常首先做错了什么。数值 1
和 1.0
都等于 True
,所以如果你有一个变量可以是数字或布尔值,这个测试可能会给你意想不到的结果。拥有一个可以是布尔值或非布尔值的变量通常也是一种反模式。
【讨论】:
【参考方案2】:首先,np.nan
的工作方式与 float('nan')
相同。
import numpy as np
print(type(np.nan)) # <class 'float'>
Python 通常says:
默认情况下,一个对象被认为是true,除非它的类定义了 返回 False 的
__bool__()
方法或__len__()
方法 使用对象调用时返回零。
然后对于内置数字类型,它说任何零都被认为是False
:
任何数字类型的零:0、0.0、0j、Decimal(0)、Fraction(0, 1)
当我将唯一的浮点类型加粗为 False 时,任何其他浮点数都被视为True
。
所以:
print(bool(float('nan'))) # True
Numpy 的行为也与 python 一样。
当您说if obj:
时,python 试图通过bool()
的帮助来获取obj
的真值,这确实查看了__bool__
和__len__
特殊方法。 (__bool__
如果实施,优先级更高)。
【讨论】:
"np.nan 的工作方式与 float('nan')" 当然,因为np.nan
*是与 float('nan')
具有相同类型值的相同类型的对象.
"当你说 if obj:
时,它会变成 if bool(obj) is True:
不,python 会这样做。Numpy 无法控制这种行为。实际上,主要的 numpy 类型,np.ndarray
,抛出一个错误。因为numpy.ndarray.__bool__
引发了一个错误(除非你正在使用一个带有一个元素的numpy.ndarray,令人困惑)
@juanpa.arrivillaga 是的,在这两种情况下它都会抛出一个 ValueError ,我的意思是 (if arr:
) 和 bool(arr)
@juanpa.arrivillaga 不是因为if arr:
试图在arr
上调用bool()
吗?
正因为如此。让我准确地说,条件语句的机制,例如if something:
被处理是解释器运行时的一部分,即语言本身。本质上,使用了bool(something)
和len(something)
,对象可以决定如何使用特殊的方法钩子来响应它,__bool__
和__len__
我并不反对你的回答,只是建议一种改写方式让它更清楚。【参考方案3】:
我建议使用显式条件。如果 a!=0,第二个选项将始终为您提供 True,此外,当您不编写代码时,这种类型的条件会令人困惑。
【讨论】:
【参考方案4】:这意味着变量a
的值是否等于True
。
if a == True:
但是这个变量a
有没有值。
if a:
【讨论】:
以上是关于将“a == True:”简化为“a”——这是个好主意吗?的主要内容,如果未能解决你的问题,请参考以下文章