python - Python中的“0就是0”总是“真”吗?
问题描述
Python 3.8(或 CPython 3.8?)添加了警告
SyntaxWarning: "is" with a literal. Did you mean "=="?
对于代码0 is 0
。
is
我理解警告,并且知道和之间的区别==
。
但是,我也知道 CPython 会缓存小整数的对象并在其他情况下共享它。(出于好奇,我刚刚再次检查了代码(标头)。小整数缓存在tstate->interp->small_ints
.
中0
,并且1
更特别,全局存储在_PyLong_Zero
and中_PyLong_One
。所有新创建的int
s 都是通过PyLong_FromLong
,首先检查它是否是小整数整数和缓存。)
鉴于这种背景,如果你知道你有一个int
对象,你可以说支票x is 0
应该是安全的,对吧?此外,您可以得出0 is 0
应该始终是True
,对吗?或者这是 CPython 的实现细节,其他解释器不遵循这个?哪个口译员不遵循这个?
尽管有这个更通用的问题(我只是好奇),请考虑这个更具体的(示例)代码:
def sum1a(*args):
y = 0
for x in args:
if y is 0:
y = x
else:
y = y + x
return y
对比:
def sum1b(*args):
y = 0
for x in args:
if y == 0:
y = x
else:
y = y + x
return y
对比:
def sum1c(*args):
y = None
for x in args:
if y is None:
y = x
else:
y = y + x
if y is None:
return 0
return y
对比:
def sum2(*args):
y = 0
for x in args:
y = y + x
return y
我有时更喜欢的原因sum1*
是sum2
,取决于库,sum1*
确实可以更有效。例如,如果参数是一个 Numpy/TensorFlow/PyTorch 数组,你真的会在这里节省一个(可能成本高昂的)操作。
我更喜欢的原因sum1a
是sum1b
它sum1b
会在某些输入上中断。例如,如果输入是一个 Numpy 数组,这将不起作用。
当然,您可以使用sum1c
代替sum1a
. 然而,sum1a
更短。所以这个更好看?
如果原始问题的答案是这应该始终有效,并且如果您同意这sum1a
是最好的选择,那么您将如何摆脱警告?有简单的解决方法吗?一般来说,我可以看到警告很有用。所以我不想完全禁用它。我只想为这个特定的语句禁用它。
也许我可以将它包装在一个函数中:
def is_(a, b):
return a is b
然后只需使用if is_(y, 0): ...
. 这行得通吗?这是一个好主意吗?
解决方案
推荐阅读
- r - 无法将 tidyverse 代码从子集应用到整个数据
- javascript - 将递归函数转换为递归箭头函数
- r - 为什么 ifelse 和 if 语句不一样?
- python - 如何从列表字典的值中获取所有键?
- javascript - 更改后的jexcel表SUM列
- html - 带有“section”元素的语义
- servicestack-text - FromObjectDictionary 方法中的错误返回值
- c# - DevExtreme - 带有 JSON 数据源和表单对象的手风琴内部表单
- swift - 主窗口并不总是在 applicationDidFinishLaunching 中初始化
- delphi-xe7 - 为什么 Delphi XE 7 将组件/事件定义放在错误的部分?