今天我在Python中了解了is
关键字并尝试了以下内容:
>>> x=2+2
>>> y=4
>>> x is y
True
我开始尝试使用整数is
因为我知道答案是False
- 所以我发现结果非常令人惊讶!为了给出一些上下文,我的背景是C ++和C#,其中值类型和对象类型之间存在区别。在Python中,正如我现在所知,一切都是引用类型。
x is y
True
的原因似乎与此问题[{3}}中解释的相同,后者与使用is
字符串相关。即运行时环境通过共享或“实习”整数来保存内存,就像它对字符串一样 - 这在问题的答案中有更详细的解释:How is the 'is' keyword implemented in Python?我在我的初始帖子后找到了。
我发现令人惊讶的另一件事是is
返回的值是依赖于实现的。这与我的主要问题有关。在有关is
w.r.t字符串实现的引用问题中,有一些关于何时使用is
的讨论,有几个用户表示他们(几乎)从不使用它。所以我的问题是,当应该使用is
关键字时?什么是规范示例或一般规则?
答案 0 :(得分:17)
当您想知道两个对象是否是同一个对象时,应该使用is
。当您想知道两个对象是否具有相同的值时,请不要使用它。
有一个规范的例子,但遗憾的是它不是很有帮助。人们会告诉您始终使用None
代替x is None
来测试x == None
值。但是,这些案例之间几乎没有实际差别。 (有关解释,请参阅this question。)
在某些情况下,您最终可能会创建具有相同值但是不同对象的对象。例如,你可以想象创造一个幻想战争游戏,玩家可以神奇地创造小兵来对抗他的对手。所以玩家可以创造100个相同的兽人或其他什么。每个orc都可以用一个对象来表示,它们是相同的,因为它们具有相同的属性,但仍然不同,因为它们将有100个独立的对象。现在,如果对手试图投射一个"火球"在其中一个兽人上拼写,同时在同一回合中玩家试图施放"防止火灾"在兽人身上,你可能想检查火球的目标是否is
保护法术的目标。平等是不够的,因为所有的兽人都是相同的,但只有一个特定的兽人是每个法术的目标,你想知道这两个目标是否是同一个物体。这是一个相当人为的例子,但应该对你可能最终使用is
的情况有一个广泛的了解。
答案 1 :(得分:14)
“is
测试身份,而不是相等。这意味着Python只是比较对象所在的内存地址”
有一个简单的经验法则告诉你何时使用==或is。
==
用于价值平等。如果您想知道两个对象是否具有相同的值,请使用它。is
用于引用相等。如果您想了解是否可以使用它
两个引用引用相同的对象。通常,当您将某些内容与简单类型进行比较时,通常会检查值是否相等,因此您应该使用==。
如果两个变量指向同一个对象, is
将返回True,如果变量引用的对象相等,则返回=。
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True
第二个测试只能起作用,因为Python会缓存小整数对象,这是一个实现细节。对于较大的整数,这不起作用:
>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
The same holds true for string literals:
>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True
注意:“由于自动垃圾收集,空闲列表和描述符的动态特性,您可能会注意到is运算符的某些使用中看似异常的行为,例如涉及实例之间比较的那些行为方法或常数。“
由于CPython参考实现的工作方式,如果您错误地使用是比较整数上的引用相等性,您将得到意外和不一致的结果:
>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False
这几乎是我们的预期:a和b具有相同的值,但却是不同的实体。但是这个呢?
>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True
这与之前的结果不一致。这里发生了什么?事实证明,由于性能原因,Python的引用实现将-5..256范围内的整数对象缓存为单例实例。这是一个证明这一点的例子:
>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
...
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False
这是另一个不使用的明显原因:当你错误地将它用于值相等时,行为就会被实现。
答案 2 :(得分:2)
首先,x是y的原因是True与此问题中解释的相同,如何在Python中实现'is'关键字?这与使用字符串有关吗?
它很相似。 -5
到256
的整数已缓存。这用于性能目的。
所以我的问题是,什么时候应该使用is关键字?
您可以使用is
检查两个引用是否属于同一对象(它检查对象身份)。此外,当您将对象引用与is
进行比较时,建议使用None
:
if some_object is None:
# ...