玩id()
。开始查看不同对象中相同属性的地址。但是现在我觉得这没关系。下到代码:
class T(object):
pass
class N(object):
pass
首次测试(在交互式控制台中):
n = N()
t = T()
id(n)
# prints 4298619728
id(t)
# prints 4298619792
实际上,这并不奇怪。 n.__class__
与t.__class__
不同,因此很明显它们不可能是同一个对象。目前这些对象之间的__class__
仅是否有差异?假设否,为:
>>> n1 = N()
>>> n2 = N()
>>> id(n1) == id(n2)
False
或者Python只是创建单独的对象,即使它们在内容方面完全相同,而不是首先将名称n1
,n2
分配给同一对象(在内存中)并在n1
或n2
被修改时重新分配?为什么这样?我明白这可能是一个常规,优化,情绪,低级别问题的问题(不要饶恕我),但我仍然很好奇。
现在,和以前一样,T()
& N()
- 在shell中一个接一个地执行:
>>> id(N())
4298619728
>>> id(N())
4298619792
>>> id(N())
4298619728
>>> id(N())
4298619792
为什么玩杂耍?
但是这里出现了奇怪的部分。同样,相同的类,shell:
>>> id(N()), id(T())
(4298619728, 4298619728)
>>> id(N()), id(T())
(4298619728, 4298619728)
>>> id(N()), id(T())
(4298619728, 4298619728)
不仅杂耍停止,而且N()和T()似乎是同一个对象。由于它们不可能,我理解为N()
在id()
调用后被撤销,在整个陈述结束之前。
我意识到这可能是一个艰难的回答。但是我希望有人可以告诉我我在这里观察到的是什么,我的理解是否正确,分享一些关于解释器内部工作和记忆管理的黑暗魔法,或者可能指出一些关于这个主题的好资源?
感谢您抽出宝贵时间。
答案 0 :(得分:6)
答案 1 :(得分:5)
文档says it all:
id(object)
:返回对象的“标识”。这是一个整数(或长整数) 整数)保证对于该对象是唯一的和常量的 在其一生中。两个具有非重叠寿命的对象可以 具有相同的id()值。
每当调用构造函数时,都会创建一个新对象。该对象的id与当前存活的任何其他对象的id不同。
>>> n1 = N()
>>> n2 = N()
>>> id(n1) == id(n2)
False
两个对象的“内容”无关紧要。它们是两个不同的实体;他们会得到不同的ID似乎是完全合乎逻辑的。
在CPython中,id只是内存地址。它们确实被回收:如果一个对象被垃圾收集,将来某个时候创建的另一个对象可能获得相同的id。这是您在重复的id(N()), id(T())
测试中看到的行为:由于您没有保留对新创建的对象的引用,因此解释器可以自由地收集它们并重用它们的ID。
ids的回收显然是一个实施/平台人工制品,不应该依赖。
答案 2 :(得分:1)
我可能错了,但我认为您正在看垃圾收集器。对N()或T()的调用会创建一个未存储在任何位置的对象,然后由GC拾取。之后,可以重复使用内存地址。
答案 3 :(得分:0)
如果您真的想要答案,请查看来源。
一般而言,除非语言保证值标识和对象标识相同,或保证实际发生(如某些情况下Java用字符串做),那么如果价值和对象标识不要感到惊讶不同。
答案 4 :(得分:0)
我认为可能会发生杂乱,因为python命令行解释器将先前执行的结果存储为_
。在命令行上,我有杂耍,但在python文件中似乎没有发生。例如,代码:
print id(X())
print id(X())
print id(X())
print id(X())
print id(X())
制作
>>> print id(X())
3078933196
>>> print id(X())
3078933004
>>> print id(X())
3078932716
>>> print id(X())
3078933196
....
但是具有相同文本的python文件会生成输出
3079140908
3079140908
3079140908
3079140908
3079140908