什么时候,如果有的话,使用'是' Python中的关键字?

时间:2014-04-05 19:47:11

标签: python keyword

今天我在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关键字时?什么是规范示例或一般规则?

3 个答案:

答案 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'关键字?这与使用字符串有关吗?

它很相似。 -5256的整数已缓存。这用于性能目的。

  

所以我的问题是,什么时候应该使用is关键字?

您可以使用is检查两个引用是否属于同一对象(它检查对象身份)。此外,当您将对象引用与is进行比较时,建议使用None

if some_object is None:
    # ...