重用Python中的名称来节省内存

时间:2012-11-12 08:22:35

标签: python variables memory memory-management copy

The Hitchhiker’s Guide to Python声明重用变量名称是好事。

foo = Spam()
bar = foo.eggs()

我同意它。它使代码可读。

如果变量是40 MB的数据怎么办?它会自行复制并总共有80 MB吗?

foo = buffer  # 40 MB.
bar = foo.resize((50, 50))  # +40?

我知道在执行函数时会释放内存,但我仍然认为只有因为可读性而在一个app状态下使用两倍高的内存才是个好主意。这就像一个特例,但另一方面,特殊情况不够特别,是吗?

2 个答案:

答案 0 :(得分:5)

Python赋值只是将引用值复制到目标对象。没有数据复制。 Python变量只是Python系统字典中的名称加上值,它是对象的参考值。

实际上,你应该小心分配。任何Python赋值都意味着共享参考值。 Python赋值绝不意味着复制目标对象。使用字符串或数字等不可变对象时,不会出现任何问题。但是,当您分配任何可变对象(列表,字典,集合,某些用户对象)时,您应该知道在此之后您只给目标对象一个不同的名称(通过另一个参考值副本访问)。

将对象作为函数/方法参数传递也是一样。

答案 1 :(得分:4)

如果你必须在之前完全将这些数据放在内存中你调整它的大小(而不是只读取你关心的位),你可以这样做:

foo = buffer()
bar = foo.resize((50, 50))
del foo

或等效地:

bar = buffer().resize((50, 50))

这两个代码在运行此代码后立即使buffer的结果立即可用于垃圾回收。

此外,在这种情况下重用变量名称是完全合理的 - 如果代码中的行是一个接一个的,特别是如果foo.resize返回与foo相同类型的对象(如它似乎),然后:

foo = buffer
foo = foo.resize((50, 50))

非常好。建议不要将名称重用于完全不相关的变量 - 以便阅读代码的人可以看到变量,只需跳到最初分配的位置即可了解它是什么。当其中一个只是一次性“踩石头”来获得你关心的实际物体时,只会有一个让读者感到困惑的微不足道的风险。