5

今天我了解到 Python 会缓存表达式{},并在将其分配给变量时将其替换为新的空字典:

print id({})
# 40357936

print id({})
# 40357936

x = {}
print id(x)
# 40357936

print id({})
# 40356432

我还没有查看源代码,但我知道如何实现它。(也许当对全局的引用计数{}增加时,全局{}被替换。)

但考虑这一点:

def f(x):
    x['a'] = 1
    print(id(x), x)

print(id(x))
# 34076544

f({})
# (34076544, {'a': 1})

print(id({}), {})
# (34076544, {})

print(id({}))
# 34076544

f修改全局字典而不导致它被替换,并打印出修改后的字典。但是在外部f,尽管 id 相同,但全局字典现在是空的!

怎么了??

4

2 回答 2

6

它没有被缓存——如果你不分配{}任何地方的结果,它的引用计数是 0 并且它会立即被清除。碰巧您分配的下一个内存重用了旧内存。当你把它分配给你时,x你让它活着,然后下一个有一个不同的地址。

在您的函数示例中,一旦f返回,就没有对您的 dict 的剩余引用,因此它也被清理了,同样的事情也适用。

于 2013-03-27T19:30:08.657 回答
4

Python 在这里没有做任何缓存。id()在程序的不同点给出相同的返回值有两种可能性:

  1. id()在同一个对象上被调用了两次
  2. 调用的第一个对象id()是在创建第二个对象之前进行垃圾回收的,并且第二个对象是在与原始对象相同的内存位置创建的

在这种情况下,它是第二个。这意味着即使print id({}); print id({})可能两次打印相同的值,每次调用都在不同的对象上。

于 2013-03-27T19:31:36.743 回答