栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Cython:“无法转换Python对象”错误

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Cython:“无法转换Python对象”错误

这个问题经常出现,但是我找不到一个很好的重复目标,这超出了“只要这样做就行”的范围。

这是一种非常常见的情况:您尝试将一些python数据结构传递给需要指针的c代码

int *, double*,...
。但是,指针不是python对象,因此我们无法将它们从python代码传递到python代码。

用Cython可以自动处理转换到

int
double
float
等等,甚至
char *
(它是一个空终止的c-字符串)和一些STL-
容器
,而不是指针(
char *
作为一个例外)。

有两种最常见的情况:

  1. python数据的内部表示形式已经是一个c数组(
    array.array
    ,numpy-arrays)。
  2. 内部表示形式不是连续数组(例如
    list

1.通过内存视图传递:

在python中,我们无法以某种方式获取指针,因此必须在cython中完成。将

array.array
or或
numpy.array
(或任何其他支持buffer-
protocol的
python对象
ctypes.Array
,例如,参见此SO-
question
)传递给cython函数的首选是内存视图:

def myTest(int[:] arr):    testFn(&arr[0])

现在从python调用它:

>>> import array>>> a=array.array('i', [0]*2)>>> import caller>>> caller.myTest(a)>>> aarray('i', [1, 2]) #it worked

以下重要

  1. int[:]
    是python对象(类型化的内存视图),因此可以将其传递给python函数(
    def
    cpdef
    )。
  2. &arr[0]
    用于获取内存视图的缓冲区的地址。其结果是类型
    int *
  3. 该函数的调用是“类型安全的”,您不能例如
    array.array('I', [0]*2)
    将其传递给它,因为它不是
    int
    -memory-view,而是
    unsigned int
    -memory-view。

2.传递非连续内存(例如列表):

list
与Co.合作的还有更多工作:信息没有存储在普通的c数组中,因此我们需要先将其复制到连续内存中,将此temp变量传递给我们的c代码,然后将结果复制回列表中,即cython函数可能如下所示

import arraydef myTest2(lst):    tmp=array.array('i', lst)    myTest(tmp)    lst.clear()    lst.extend(tmp)

现在,在重新加载

caller
模块后:

>>> lst=[0,0]>>> caller.myTest2(lst)[1, 2]

因此,可以将列表的内容传递给c函数,但是基本上您想使用它,

array.array
或者
numpy.array
如果需要使用c代码进行数据交换。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/669831.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号