【问题标题】:Accessing xrange internal structure访问 xrange 内部结构
【发布时间】:2010-12-20 03:26:12
【问题描述】:

我正在尝试使用 ctypes 从内部 python 结构中提取数据。也就是说,我正在尝试读取 xrange 中的 4 个字段:

typedef struct {
    PyObject_HEAD
    long    start;
    long    step;
    long    len;
} rangeobject;

是否有任何标准方法可以在 python 本身中获取这些字段?

【问题讨论】:

    标签: python ctypes cpython xrange


    【解决方案1】:

    ctypes 模块并非用于访问 Python 内部。 ctypes 让您可以使用 C 术语处理 C 库,但使用 Python 进行编码。

    您可能想要一个 C 扩展,它在许多方面与 ctypes 是相反的。使用 C 扩展,您可以使用 Python 术语处理 Python 代码,但使用 C 语言处理代码。

    更新:既然您想要纯 Python,为什么需要访问内置 xrange 对象的内部? xrange 非常简单:用 Python 创建你自己的,然后用它做你想做的事。

    【讨论】:

    • 在理想的世界中,我会使用一个。但是,我分发的内容必须是纯 python 编写的;我不能让用户编译 python 扩展。
    • 我正在实现一个库(PiCloud(.com) 的开源部分),它需要在 python 2.5 中序列化这些对象。注意:我总是可以先做一个 str(xrange_object) 然后解析,但除了非常笨拙之外,我还试图处理其他 C 对象。
    【解决方案2】:

    您可以在没有ctypes 的情况下访问您需要的数据:

    >>> obj = xrange(1,11,2)
    >>> obj.__reduce__()[1]
    (1, 11, 2)
    >>> len(obj)
    5
    

    请注意,__reduce__() 方法正是用于序列化。阅读this chapter in documentation了解更多信息。

    更新:但请确保您也可以使用ctypes 访问内部数据:

    from ctypes import *
    
    PyObject_HEAD = [
        ('ob_refcnt', c_size_t),
        ('ob_type', c_void_p),
    ]
    
    class XRangeType(Structure):
        _fields_ = PyObject_HEAD + [
            ('start', c_long),
            ('step', c_long),
            ('len', c_long),
        ]
    
    range_obj = xrange(1, 11, 2)
    
    c_range_obj = cast(c_void_p(id(range_obj)), POINTER(XRangeType)).contents
    print c_range_obj.start, c_range_obj.step, c_range_obj.len
    

    【讨论】:

    • 对不起,我忘了在问题中提到我需要与 Python 2.5 兼容。序列化仅在 python 2.6 中添加。
    • 完美运行;非常感谢。 (现在很清楚如何对一般类型执行此操作)
    猜你喜欢
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多