Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
# RAM usage: 2100
>>> class Test:
... def __init__(self, i):
... self.one = i
... self.hundred = 100*i
...
# RAM usage: 2108
>>> list1 = [ Test(i) for i in xrange(10000) ]
# RAM usage: 4364
>>> del(list1)
# RAM usage: 2780
>>> list2 = [ {"one": i, "hundred": 100*i} for i in xrange(10000) ]
# RAM usage: 3960
>>> del(list2)
# RAM usage: 2908
为什么对象列表的内存量是等效词典列表的两倍?我认为一个对象会更有效率,因为不需要为每个对象存储属性名称的副本。
答案 0 :(得分:10)
如果您在Python中定义一个类(而不是将其编写为C扩展名),那么默认情况下它将使用字典来存储其所有属性。这就是为什么它不可能小于字典,以及为什么你可以为大多数Python对象分配任意属性。
如果您事先知道对象需要哪些属性,则可以在课程中使用__slots__
属性 [docs] 指定它们。这允许Python更高效,并且不需要每个对象的完整字典。在您的情况下,您可以通过添加
__slots__ = ["one", "hundred"]
位于class Test:
下方的一行。但是,如果这足以使对象比字典小,我会有点惊讶; Python的字典经过高度优化,可用于少量值。 (编辑:我有点惊讶,显然它确实使它们比字典小。)
答案 1 :(得分:1)
Python使用词典实现对象属性查找,即当您要求someObject.x
将其转换为引擎盖时someObject.__dict__["x"]
。 (是的,您可以输入 - 可以使用__dict__
属性名称访问基础词典。)
因此,首先,每个对象实例存储一次 属性名称(请记住 - Python不确定类中的每个对象是否具有相同名称的相同属性! )。其次,除了存储该字典之外,还有一些额外的数据可以进入一个字体不需要处理的对象(例如指向其类方法的指针)。
答案 2 :(得分:0)
我认为一个对象会更有效率,因为不需要为每个对象存储属性名称的副本。
您对内存重用的假设是错误的。
组成词典键的字符串是固定的,对于每个词典,使用的键只是对相同实习数据的引用。
类的属性也存储在字典中。