python - 在临时对象共享相同内存地址的情况下,“is”如何工作?
问题描述
请注意,这个问题可能(是?)特定于 CPython。
假设您有一些列表,并检查列表的副本以确认彼此的身份:
>>> a=list(range(10))
>>> b,c=a[:],a[:]
>>> b is c
False
>>> id(b), id(c)
(3157888272304, 3157888272256)
那里没有很大的震动。但如果我们以一种更短暂的方式来做这件事,一开始事情可能看起来有点奇怪:
>>> a[:] is a[:]
False # <- two ephemeral copies not the same object (duh)
>>> id(a[:]),id(a[:])
(3157888272544, 3157888272544) # <- but two other ephemerals share the same id..? hmm....
...直到我们认识到这里可能发生了什么。我没有通过查看 CPython 实现来确认这一点(我几乎看不懂 c++,所以说实话,这将是浪费时间),但至少看起来很明显,即使两个对象具有相同的 id,CPython 也很聪明足以知道它们不是同一个对象。
假设这是正确的,我的问题是:CPython 使用什么标准来确定两个临时对象是否不是同一个对象,因为它们具有相同的 id(可能是出于效率原因 - 见下文)?它是否可能正在查看它被标记为垃圾收集的时间?创建时间?或者是其他东西...?
我关于为什么它们具有相同 id 的理论是,很可能,CPython 知道列表的临时副本已经制作并等待被垃圾收集,并且它只是有效地重用相同的内存位置。如果答案也可以澄清/确认这一点,那就太好了。
解决方案
两个不可变的对象,共享相同的地址,在你看来,彼此无法区分。
问题是,当你做a[:] is a[:]
这两个对象不在同一个地址时——为了让身份运算符is
比较两个对象,两个操作数都必须存在——所以,当的本机代码is
实际上正在运行。
另一方面,当您id(a[:]),id(a[:])
在第一次调用时,括号内的对象在函数调用完成后立即没有任何引用id
,并被销毁,释放内存块以供第二次使用a[:]
。
推荐阅读
- python - 而python中的else不执行else
- android - Cordova 应用程序:“无法实例化活动 ComponentInfo”
- python - 我如何告诉 jsonschem 需要一个/多个 patternProperties?
- c++ - 如何制作使用协议缓冲区的项目?
- php - 你如何让php发送电子邮件
- fastreport - 如何在万神殿的 fastreport 中获取从日期和到日期的输入
- cypress - 如何使用赛普拉斯深入比较 2 个对象
- google-cloud-platform - 使用 Codeigniter 将文件上传到 Google Cloud Storage
- isabelle - 如何查看所有活动的 Isabelle 会话?
- javascript - 将 JavaScript 数组字符串化以发送到 PHP 脚本