在以下示例中使用dictionary
和objects
进行操作时,有人可以解释幕后的内存会发生什么:
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
数据结构中的值大小相同,但类型之间的差异让我想知道幕后会发生什么?
该示例是否使objects
比dictionaries
更有效?
我使用的是Ubuntu 14.04和Python 2.7.6
答案 0 :(得分:2)
请注意,sys.getsizeof
为您提供对象本身的大小,但这不是整个故事。对象具有各种属性,这些属性也有助于整体内存占用。例如,类的实例具有__dict__
,其中包含其属性的值:
>>> o = O()
>>> o.__dict__
{}
>>> sys.getsizeof(o.__dict__)
140
注意三件有趣的事情:
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
该示例是否使对象比字典更有效?
完全没有;首先,正如我所示,对象通常使用字典实现(通过定义__dict__
,有一种方法可以不为每个实例创建__slots__
在课堂上预先定义的属性,但我不会在这里进入)和词典本身就是对象(虽然内置类型因我赢得的原因而略有不同)!
一般情况下,除非出现问题,否则不要担心内存细节 - 如果需要状态和行为(属性和方法),请定义一个类如果您只需要州,请使用字典。
答案 1 :(得分:1)
两个对象的简单比较表明,字典是一个比简单类更复杂的对象:
>>> dt = {}
>>> dir(dt)
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__',
'__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__',
'__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get',
'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem',
'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']
针对:
>>> class O(object):
... var1 = 'asdfasdfasfasdfasdfasdfasdf'
... var2 = 255
...
>>> o = O()
>>> dir(o)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
'__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', 'var1', 'var2']