python html指针可以动的仪表盘 python有指针吗?

admin2024-05-30  21

我正在尝试为包含C指针的cython类编写一个__reduce __()方法,但到目前为止,我找到了关于最佳方法的信息.当使用numpy数组作为成员数据时,有很多关于如何正确编写__reduce __()方法的例子.我想远离Numpy数组,因为它们似乎总是存储为python对象,并且需要调用python API.我来自C背景,所以我很乐意使用对malloc()和free()的调用手动处理内存,并且我试图将python交互保持在绝对最小值.

但是我遇到了一个问题.我需要在我正在创建的类中使用与copy.deepcopy()等效的东西,从最终将使用它的Python脚本.我发现执行此操作的唯一好方法是通过实现__reduce __()方法为该类实现pickle协议.对于大多数原语或python对象来说,这是微不足道的.但是,对于如何为动态分配的C数组执行此操作,我绝对不知所措.显然我无法返回指针本身,因为底层内存在重建对象时会消失,那么最好的方法是什么?我确信这将需要修改__reduce __()方法以及一个或两个__init __()方法.

我已经阅读了关于pickling扩展类型found here的python文档以及关于选择cython类(例如this question)的堆栈溢出的所有其他问题.

我的类的精简版看起来像这样:

cdef class Bin:
cdef int* job_ids
cdef int* jobs
cdef int primitive_data
def __cinit__(self):
self.job_ids = malloc(40 * sizeof(int))
self.jobs = malloc(40 * sizeof(int))
def __init__(self, int val):
self.primitive_data = val
def __dealloc__(self):
free(job_ids)
free(jobs)
def __reduce__(self):
return (self.__class__, (self.primitive_data))

解决方法:

一种方法是将数组中的数据序列化为Python字节数组. __reduce__方法首先调用get_data方法,该方法将数据指针强制转换为< char *>然后到< bytes> (如果你试图直接去那里,Cython不知道该怎么做). __reduce__返回此对象,以及对可用于使用set_data方法重新创建实例的rebuild函数(模块级函数,而不是方法!)的引用.如果你需要传递多个数组,就像在你的例子中一样,你只需要接受更多的参数来重建和扩展__reduce__返回的元组.

我没有做太多测试,但它似乎工作.如果您传递格式错误的数据,它可能会爆炸.

from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
from libc.string cimport memcpy
cdef int length = 40
cdef class MyClass:
cdef long *data
def __cinit__(self):
self.data = PyMem_Malloc(sizeof(long)*length)
if not self.data:
raise MemoryError()
cdef bytes get_data(self):
return (self.data)[:sizeof(long)*length]
cdef void set_data(self, bytes data):
memcpy(self.data, data, sizeof(long)*length)
def set_values(self):
# assign some dummy data to the array 0..length
for n in range(0, length):
self.data[n] = n
def get(self, i):
# get the ith value of the data
return self.data[i]
def __reduce__(self):
data = self.get_data()
return (rebuild, (data,))
def __dealloc__(self):
PyMem_Free(self.data)
cpdef object rebuild(bytes data):
c = MyClass()
c.set_data(data)
return c

示例用法(假设MyClass位于hello.pyx中):

import hello
import pickle
c1 = hello.MyClass()
c1.set_values()
print('c1', c1)
print('fifth item', c1.get(5))
d = pickle.dumps(c1)
del(c1) # delete the original object
c2 = pickle.loads(d)
print('c2', c2)
print('fifth item', c2.get(5))
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!