मैं ब्रैंडन रोड्स कोड Routines that examine the internals of a CPython dictionary को संशोधित करने की कोशिश कर रहा हूं ताकि यह सीपीथन 3.3 के लिए काम करे।पायथन 3.3 dict: पाइथन कक्षा में स्ट्रक्चर PyDictKeysObject को कैसे परिवर्तित करें?
मेरा मानना है कि मैंने इस संरचना का सफलतापूर्वक अनुवाद किया है।
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, CFUNCTYPE
LOOKUPFUNC = CFUNCTYPE(POINTER(PyDictKeyEntry), POINTER(PyDictObject),
py_object, c_ulong, POINTER(POINTER(py_object)))
class PyDictKeysObject(Structure):
"""A key object"""
_fields_ = [
('dk_refcnt', c_ssize_t),
('dk_size', c_ssize_t),
('dk_lookup', LOOKUPFUNC),
('dk_usable', c_ssize_t),
('dk_entries', PyDictKeyEntry * 1),
]
PyDictKeysObject._dk_entries = PyDictKeysObject.dk_entries
PyDictKeysObject.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."""
pass
def slot_of(self, key):
"""Find and return the slot at which `key` is stored."""
pass
def slot_map(self):
"""Return a mapping of keys to their integer slot numbers."""
pass
PyDictObject._fields_ = [
('ob_refcnt', c_ssize_t),
('ob_type', c_void_p),
('ma_used', c_ssize_t),
('ma_keys', POINTER(PyDictKeysObject)),
('ma_values', POINTER(py_object)), # points to array of ptrs
]
नोट: आप [hg.python.org सीधे] (http://hg.python.org/cpython/file/3.3/Objects/dictobject.c#l72) से लिंक कर सकते हैं। 'Dict_lookup_func' परिभाषित करने के लिए' ctypes.CFUNCTYPE' आज़माएं। – jfs
अपडेट: मैंने अब CFUNCTYPE का उपयोग करके dk_lookup का प्रकार घोषित किया है: – LeslieK
@ जेएफ। सेबेस्टियन: धन्यवाद। मैंने अब CFUNCTYPE का उपयोग कर dk_lookup के प्रकार की घोषणा की है। क्या dk_entries सही दिखते हैं? सी कोड dk_entries [1] का उपयोग करता है। – LeslieK