有人可以解释一下在以下示例中使用字典
和对象
进行操作时幕后的内存会发生什么吗:
In [52]: class O(object):
....: var1 = 'asdfasdfasfasdfasdfasdfasdf'
....: var2 = 255
....:
In [53]: dt = {'var1': 'asdfasdfasfasdfasdfasdfasdf', 'var2': 255}
In [55]: o = O()
In [57]: sys.getsizeof(o)
Out[57]: 64
In [58]: sys.getsizeof(dt)
Out[58]: 280
根据上面的值,接下来的事情很奇怪
In [68]: sys.getsizeof(o.var1)
Out[68]: 64
In [69]: sys.getsizeof(o.var2)
Out[69]: 24
In [70]: sys.getsizeof(dt['var1'])
Out[70]: 64
In [71]: sys.getsizeof(dt['var2'])
Out[71]: 24
数据结构中的值大小相同,但类型之间的差异让我想知道幕后发生了什么?
该示例是否使对象
比字典
更有效?
我使用 Ubuntu 14.04 和 Python 2.7.6
最佳答案
请注意 sys.getsizeof
给你对象本身的大小,但这并不是全部。对象具有各种属性,这些属性也会影响总体内存占用。例如,类的实例具有 __dict__
,它保存其属性的值:
>>> o = O()
>>> o.__dict__
{}
>>> sys.getsizeof(o.__dict__)
140
注意三件有趣的事情:
- 这也是一个字典 - 这种数据结构在 Python 中被广泛使用,因此得到了非常好的优化;
o.__dict__
中没有任何内容,因为var1
和var2
是类属性,存储在O
上,而不是实例属性;和- 尽管
o.__dict__
中什么都没有,它的大小仍然与dt
相同,因为字典初始化时有足够的空间容纳 (IIRC) 八个键,以避免在向其中添加项目时频繁调整大小(有关字典实现的更多信息,请参阅 "The Mighty Dictionary" )。
另请注意,如果我们在两种情况下比较实例的大小加上类(这是一个更公平的比较),差距就会缩小:
>>> sys.getsizeof(o) + sys.getsizeof(O)
484
>>> sys.getsizeof(dt) + sys.getsizeof(dict)
576
Does the example makes objects more effective over dictionaries?
完全没有;一方面,正如我所展示的,对象通常使用字典来实现(有一种方法可以不为每个实例创建__dict__
,通过定义预定义属性的__slots__
类,但我不会在这里深入讨论),而字典本身就是对象(尽管内置类型略有不同,原因我不会详述)!
一般来说,不要担心内存细节,除非它成为问题 - 如果您需要状态和行为(属性和方法)并使用,请定义一个类如果您只需要状态,则字典。
关于Python 字典大小与对象大小效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31006448/