python对象和类的内存布局是什么?

时间:2013-06-13 14:31:47

标签: python sizeof

Python interpeter为对象存储了哪些数据?
例如,在以下代码中:

class MyClass:
    pass

if __name__ == "__main__":
    c = MyClass()
    import sys
    print sys.getsizeof(c),sys.getsizeof(MyClass)

为什么输出72和104?为什么类比对象实例更大?类和对象必须存储什么,占用72个字符和104个字符?

令人惊讶的是,当我运行时:

class MyClass:
    def __init__(self):
        self.mIntValue = 1024
        self.mStringValue = "hust";

if __name__ == "__main__":
    c = MyClass()
    import sys
    print sys.getsizeof(c),sys.getsizeof(MyClass)

输出仍然是72和104,但我添加了两个额外的属性,所以我猜对象应该变得“更大”。好吧,结果似乎不是这样。

1 个答案:

答案 0 :(得分:5)

基本上,pythons类和实例都是对象。当您测试MyClass()的大小时,您正在查询实例对象的内存大小,当您为MyClass执行此操作时,您正在测试类对象的大小。

两个对象都有自己的字段,这就是为什么大小不同的原因,并且类对象需要比实例更多的内存也就不足为奇了。

python中的类的实例是一种将名称与python对象(函数,字段等)相关联的字典。实际上,它们存储在MyClass().__dict__字典中。因此,如果您向类添加更多字段,则大小不会更改,因为该类指向依次存储字段的__dict__对象。

sys.getsizeof(MyClass().__dict__)的测试结果也是一个固定的长度。因为python字典将其密钥存储在keys列表中,并将其值存储在values列表中(具有智能散列关联等)。

因此,如果您希望看到课程规模的增长,您可以这样做:

从ipython转储

In [11]: class A():
   ....:     def __init__(self, **kwargs):
   ....:         for k,a in kwargs.items():
   ....:             self.__dict__[k]=a
   ....:
   ....:

In [14]: a1 = A(a=2)

In [15]: a2 = A(a=2,b=3,c='aaaa')

In [16]: import sys

In [17]: sys.getsizeof(a1.__dict__)
Out[17]: 140

In [18]: sys.getsizeof(a2.__dict__)
Out[18]: 140

In [19]: sys.getsizeof(a1.__dict__.keys())
Out[19]: 40

In [20]: sys.getsizeof(a2.__dict__.keys())
Out[20]: 48

In [21]: sys.getsizeof(a2.__dict__.keys()+a2.__dict__.values())
Out[21]: 60

In [22]: sys.getsizeof(a1.__dict__.keys()+a2.__dict__.values())
Out[22]: 52

希望这可以解释一些事情。