今天我is在Python中学习了关键字,并尝试了以下方法:
>>> x=2+2
>>> y=4
>>> x is y
True
Run Code Online (Sandbox Code Playgroud)
我开始尝试is整数,因为我知道答案是False- 所以我发现结果非常令人惊讶!为了给出一些上下文,我的背景是C++和C#,其中值类型和对象类型之间存在区别.在Python中,正如我现在所知,一切都是引用类型.
看来,原因x is y是True是因为在这个问题解释的一样,怎么是"是"用Python实现关键字?,与使用is字符串有关.即运行时环境通过共享或"实际"整数来保存内存,就像它对字符串一样 - 这在问题的答案中有更详细的解释:Python"is"运算符在我初始化后发现的整数表现出乎意料帖子.
我发现令人惊讶的另一件事是is返回的值是依赖于实现的.这与我的主要问题有关.在引用的关于iswrt字符串实现的问题中,有一些关于何时使用的讨论is,有几个用户表示他们(几乎)从不使用它.所以我的问题是,什么时候应该使用is关键字?什么是规范示例或一般规则?
Bre*_*arn 18
is当您想知道两个对象是否是同一个对象时,您应该使用它.当您想知道两个对象是否具有相同值时,请不要使用它.
有一个规范的例子,但遗憾的是它不是很有帮助.人们会告诉你总是None使用x is None而不是使用来测试值x == None.但是,这些案例之间几乎没有实际差别.(请参阅此问题以获得解释.)
在某些情况下,您最终可能会创建具有相同值但是不同对象的对象.例如,你可以想象创造一个幻想战争游戏,玩家可以神奇地创造小兵来对抗他的对手.所以玩家可以创造100个相同的兽人或其他什么.每个orc都可以用一个对象来表示,它们是相同的,因为它们具有相同的属性,但仍然不同,因为它们将有100个独立的对象.现在,如果对手试图施放"火球"拼对这些兽人之一,而在同一轮中玩家尝试投"防止火"上一个兽人,你可能要检查火球的目标咒语is的保护法术的目标.平等是不够的,因为所有兽人都是平等的,但只有一个特定的兽人是每个法术的目标,你想知道这两个目标是否是同一个对象.这是一个相当人为的例子,但应该对你可能最终使用的情况有一个广泛的了解is.
her*_*arn 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
Run Code Online (Sandbox Code Playgroud)
第二个测试只能起作用,因为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
Run Code Online (Sandbox Code Playgroud)
注意:"由于自动垃圾收集,空闲列表和描述符的动态特性,您可能会注意到is运算符的某些使用中看似异常的行为,例如涉及实例方法或常量之间的比较."
由于CPython参考实现的工作方式,如果您错误地使用的是比较整数上的引用相等性,您将获得意外和不一致的结果:
>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False
Run Code Online (Sandbox Code Playgroud)
这几乎是我们所期望的:a和b具有相同的值,但却是不同的实体.但是这个怎么样?
>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True
Run Code Online (Sandbox Code Playgroud)
这与之前的结果不一致.这里发生了什么?事实证明,由于性能原因,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
Run Code Online (Sandbox Code Playgroud)
这是另一个不使用的明显原因:当您错误地将其用于值相等时,行为就会被实现.
| 归档时间: |
|
| 查看次数: |
2704 次 |
| 最近记录: |