python 3.3 dict:如何将struct PyDictKeysObject转换为python类?

python 3.3 dict:如何将struct PyDictKeysObject转换为python类?,第1张

概述我正在尝试修改Brandon Rhodes代码 Routines that examine the internals of a CPython dictionary,以便它适用于CPython 3.3. 我相信我已成功翻译了这个结构. typedef PyDictKeyEntry *(*dict_lookup_func) (PyDictObject *mp, PyObject *key, 我正在尝试修改Brandon Rhodes代码 Routines that examine the internals of a CPython dictionary,以便它适用于cpython 3.3.

我相信我已成功翻译了这个结构.

typedef PyDictKeyEntry *(*dict_lookup_func)    (PyDictObject *mp,PyObject *key,Py_hash_t hash,PyObject ***value_addr);struct _dictkeysobject {    Py_ssize_t dk_refcnt;    Py_ssize_t dk_size;    dict_lookup_func dk_lookup;    Py_ssize_t dk_usable;    PyDictKeyEntry dk_entrIEs[1];};

我认为以下看起来很好:

from ctypes import Structure,c_ulong,POINTER,cast,py_object,CFUNCTYPELOOKUPFUNC = CFUNCTYPE(POINTER(PyDictKeyEntry),POINTER(PyDictObject),POINTER(POINTER(py_object)))class PyDictKeysObject(Structure):"""A key object"""_fIElds_ = [    ('dk_refcnt',c_ssize_t),('dk_size',('dk_lookup',LOOKUPFUNC),('dk_usable',('dk_entrIEs',PyDictKeyEntry * 1),]PyDictKeysObject._dk_entrIEs = PyDictKeysObject.dk_entrIEsPyDictKeysObject.dk_entrIEs = property(lambda s:     cast(s._dk_entrIEs,POINTER(PyDictKeyEntry * s.dk_size))[0])

这行代码现在有效,其中d == {0:0,1:1,2:2,3:3}:

obj = cast(ID(d),POINTER(PyDictObject)).contents  # works!!`

这是我在C struct PyDictObject中的翻译:

class PyDictObject(Structure):  # an incomplete type    """A dictionary object."""def __len__(self):    """Return the number of dictionary entry slots."""    passdef slot_of(self,key):    """Find and return the slot at which `key` is stored."""    passdef slot_map(self):    """Return a mapPing of keys to their integer slot numbers."""    passPyDictObject._fIElds_ = [    ('ob_refcnt',('ob_type',c_voID_p),('ma_used',('ma_keys',POINTER(PyDictKeysObject)),('ma_values',POINTER(py_object)),# points to array of ptrs]
解决方法 我的问题是访问cpython 3.3中实现的python字典的C结构.我开始使用cpython / Objects / dictobject.c和Include / dictobject.h中提供的C结构.定义字典涉及三个C结构:PyDictObject,PyDictKeysObject和PyDictKeyEntry.每个C结构到python的正确转换如下.评论表明我需要修复的地方.感谢@eryksun指导我一路走来!
class PyDictKeyEntry(Structure):"""An entry in a dictionary."""    _fIElds_ = [        ('me_hash',c_ulong),('me_key',py_object),('me_value',]class PyDictObject(Structure):    """A dictionary object."""    passLOOKUPFUNC = CFUNCTYPE(POINTER(PyDictKeyEntry),POINTER(POINTER(py_object)))class PyDictKeysObject(Structure):"""An object of key entrIEs."""    _fIElds_ = [        ('dk_refcnt',# a function prototype per docs         ('dk_usable',# an array of size 1; size grows as keys are inserted into dictionary; this variable-sized fIEld was the trickIEst part to translate into python    ]   PyDictObject._fIElds_ = [    ('ob_refcnt',# Py_ssize_t translates to c_ssize_t per ctypes docs    ('ob_type',# Could not find this in the docs    ('ma_used',# Py_Object* translates to py_object per ctypes docs]PyDictKeysObject._dk_entrIEs = PyDictKeysObject.dk_entrIEsPyDictKeysObject.dk_entrIEs = property(lambda s: cast(s._dk_entrIEs,POINTER(PyDictKeyEntry * s.dk_size))[0])  # this line is called every time the attribute dk_entrIEs is accessed by a PyDictKeyEntry instance; it returns an array of size dk_size starting at address _dk_entrIEs. (POINTER creates a pointer to the entire array; the pointer is dereferenced (using [0]) to return the entire array); the code then accesses the ith element of the array)

以下函数提供对python字典底层的PyDictObject的访问:

def dictobject(d):    """Return the PyDictObject lying behind the Python dict `d`."""    if not isinstance(d,dict):        raise TypeError('cannot create a dictobject from %r' % (d,))    return cast(ID(d),POINTER(PyDictObject)).contents

如果d是具有键值对的python字典,则obj是包含键值对的PyDictObject实例:

obj = cast(ID(d),POINTER(PyDictObject)).contents

PyDictKeysObject的一个实例是:

key_obj = obj.ma_keys.contents

指向存储在字典的插槽0中的密钥的指针是:

key_obj.dk_entrIEs[0].me_key

使用这些类的程序以及探测插入到字典中的每个键的哈希冲突的例程位于here.我的代码是由Brandon Rhodes为python 2.x编写的代码的修改.他的代码是here.

总结

以上是内存溢出为你收集整理的python 3.3 dict:如何将struct PyDictKeysObject转换为python类?全部内容,希望文章能够帮你解决python 3.3 dict:如何将struct PyDictKeysObject转换为python类?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1204938.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存