代码之家  ›  专栏  ›  技术社区  ›  satoru

Python对象存储在内存中的结构是什么?

  •  7
  • satoru  · 技术社区  · 14 年前

    class A(object):
        def __init__(self, x):
            self.x = x
    
        def __str__(self):
            return self.x
    

    我用 sys.getsizeof 查看的 A 拿:

    >>> sys.getsizeof(A(1))
    64
    >>> sys.getsizeof(A('a'))
    64
    >>> sys.getsizeof(A('aaa'))
    64
    

    一个 不管怎样,物体都是一样的 self.x

    所以我想知道python如何在内部存储对象?

    2 回复  |  直到 7 年前
        1
  •  23
  •   Thomas Wouters    14 年前

    这取决于哪种对象,以及哪种Python实现:-)

    人们使用的时候 python ,所有Python对象都用C结构表示, PyObject . “存储对象”的所有内容实际上都存储 PyObject * PyObject公司 struct保存最基本的信息:对象的类型(指向另一个对象的指针 PyObject公司 )以及它的参考计数 ssize_t -size integer.)在C中定义的类型用它们需要存储在对象本身中的额外信息扩展此结构,有时还会单独分配额外的数据。

    PyTupleObject “扩展”PyObject结构)存储它们的长度和 PyObject公司 PyTupleObject对象 PyStringObject )存储它们的长度、缓存的hashvalue、一些字符串缓存(“interning”)簿记和数据的实际字符*。因此元组和字符串是单个内存块。

    另一方面,列表( PyListObject PyObject ** 为了他们的数据 以跟踪他们为数据分配了多少空间。因为Python存储 PyObject公司 PyDictObject )以同样的方式工作,尽管它们存储键、键的值和缓存的hashvalue,而不仅仅是项。Dict还有一些额外的开销来容纳小的Dict和专门的查找功能。

    但是这些都是C语言中的类型,你通常可以通过查看C语言源代码来了解它们将使用多少内存。中定义的类的实例 蟒蛇 而不是C并不那么容易。最简单的例子,经典类的实例,并不那么困难:它是 PyObject公司 PyObject公司* 它的类(与存储在 PyObject公司 PyObject公司* __dict__ 属性(包含所有其他实例属性)和 PyObject公司* 它的弱点(被 weakref __迪克特__ 通常是实例所独有的,因此在计算此类实例的“内存大小”时,通常也要计算属性dict的大小。但它不一定要特定于实例! 可以分配到刚好。

    新式班使礼仪复杂化。与经典类不同,新样式类的实例不是单独的C类型,因此它们不需要单独存储对象的类。他们确实有地方 __迪克特__ 要求 这个 __迪克特__ 任意属性的属性。如果类(及其所有基类)使用 __slots__ 定义一组严格的属性,而这些属性都没有命名 __迪克特__ ,实例不允许任意属性,并且未分配dict。另一方面,属性由 必须储存 在某处 . 这是通过存储 直接在PyObject结构中为这些属性的值提供指针,这与用C编写的类型非常相似 __插槽__ PyObject公司* ,无论是否设置属性。

    删除对该数据的引用,从而最终清除该数据。

    常见的 这个案子很容易弄清楚。有一些Python的内存调试器可以合理地跟踪这些事情,比如 heapy Include/<type>object.h 并在 Objects/<type>object.c . PyObject结构本身在 Include/object.h . 请记住:这是一路向下的指针,它们也占据了空间。

        2
  •  1
  •   mouad    14 年前

    在新类实例的情况下,getsizeof()返回对 PyObject PyInstance_New()

    如果您想要所有对象大小检查的列表 this .