Alb*_*ert 9 python cpython python-3.x python-internals
Python 3.8(或 CPython 3.8?)添加了警告
SyntaxWarning: "is" with a literal. Did you mean "=="?
Run Code Online (Sandbox Code Playgroud)
对于代码0 is 0。
我理解的警告,我知道之间的区别is和==。
但是,我也知道 CPython 会缓存小整数的对象并在其他情况下共享它。(出于好奇,我再次检查了代码(标头)。小整数被缓存在tstate->interp->small_ints. 中
0,1并且更加特殊,并且全局存储在_PyLong_Zero和 中_PyLong_One。所有新创建的ints 都是 viaPyLong_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
Run Code Online (Sandbox Code Playgroud)
对比:
def sum1b(*args):
y = 0
for x in args:
if y == 0:
y = x
else:
y = y + x
return y
Run Code Online (Sandbox Code Playgroud)
对比:
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
Run Code Online (Sandbox Code Playgroud)
对比:
def sum2(*args):
y = 0
for x in args:
y = y + x
return y
Run Code Online (Sandbox Code Playgroud)
我之所以有时宁愿sum1*过sum2是取决于库,sum1*才能真正提高效率。例如,如果参数是一个 Numpy/TensorFlow/PyTorch 数组,你真的会在这里节省一个(可能代价高昂的)操作。
我宁愿原因sum1a在sum1b在于sum1b将打破某些输入。例如,如果输入是一个 Numpy 数组,这将不起作用。
当然,您可以使用sum1c代替sum1a. 但是,sum1a时间较短。所以这个更好?
如果原始问题的答案是这应该始终有效,并且如果您同意这sum1a是最好的选择,那么您将如何摆脱警告?有简单的解决方法吗?一般来说,我可以看到警告很有用。所以我不想完全禁用它。我只想为这个特定的语句禁用它。
也许我可以将它包装在一个函数中:
def is_(a, b):
return a is b
Run Code Online (Sandbox Code Playgroud)
然后只需使用if is_(y, 0): .... 这行得通吗?这是一个好主意吗?
不,不是。Python的Rust 实现返回的一个例子False:
>>>>> 0 is 0
False
Run Code Online (Sandbox Code Playgroud)
这并没有错,尽管我希望在未来的版本中会有所改变。
is调用idwho 的唯一规定是返回的 id 对于给定对象是唯一且恒定的。数字(0此处)的源代码表示是否映射到不同的对象取决于实现来定义。
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |