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

打印CPython对象的底层C结构表示

  •  0
  • jmd_dk  · 技术社区  · 7 年前

    header 包含引用计数和指向对象类型的指针始终存在于该结构上。这至少是64位股票CPython 3的情况。x、 对此,我的问题受到限制。

    print_object(obj) struct 传递对象的 obj

    就实现而言,最简单的Python对象可能是 float ,这只是一个C double 附加到前面提到的标题。在这个简单的例子中,我已经能够使用 ctypes 结构 模块:

    import collections, ctypes, struct, sys
    
    header_fields = ['refcount', 'typeptr']
    Float = collections.namedtuple('Float', header_fields + ['value'])
    
    def print_object(obj):
        ptr = id(obj)
        size = sys.getsizeof(obj)
        byterep = ctypes.string_at(ptr, size)
        header = struct.unpack('qq', byterep[:16])
        if isinstance(obj, float):
            obj_struct = Float(*header, *struct.unpack('d', byterep[16:]))
        elif isinstance(obj, int):
            ...
        print(obj_struct)
    
    # Try it out
    a = 1.23
    print_object(a)
    print('The typeptr should be equal to', id(float))
    print('\nNow the refcount should have increased by 1:')
    b = a
    print_object(a)
    

    本质上,该函数读取对象的底层内存,并构建C语言的副本 结构 作为Python namedtuple ,有效地重新表示Python本身。代码应该在Python 3.5及更高版本上运行。它打印


    typeptr应等于140429307606720

    现在,参考计数应该增加1:

    以上 print_object 功能适用于 浮动 s、 同样的方法可以推广到(我想?)所有其他类型。有没有任何库(甚至Python标准库)包含这样的功能?

    1 回复  |  直到 7 年前
        1
  •  0
  •   user2357112    7 年前

    尝试自动执行此操作的问题是,没有通用的方法来获取Python类型的布局。见鬼,甚至没有一个通用的方法来判断这个结构有多大。此外,使用 class 语句不太有用 struct 对于它们的实例,尽管它们的工作方式大多类似于结构。

    对于任何想要使用的类型,您都需要自己提供结构定义,并且仍然需要对以下类型进行自定义处理: int str 有着特别奇怪的表现。