如何在cython代码中使用Python Decimal对象



我很天真地尝试了

from decimal cimport Decimal
cpdef Decimal to_decimal(str value):
return Decimal(value)

然而,当我试图编译这个时,我得到了以下错误

Error compiling Cython file:
------------------------------------------------------------
...
from decimal cimport Decimal
^
------------------------------------------------------------
helloworld.pyx:1:0: 'decimal.pxd' not found
Error compiling Cython file:
------------------------------------------------------------
...
from decimal cimport Decimal
^
------------------------------------------------------------
helloworld.pyx:1:0: 'decimal/Decimal.pxd' not found
Error compiling Cython file:
------------------------------------------------------------
...
from decimal cimport Decimal
cpdef Decimal to_decimal(str value):
^
------------------------------------------------------------
helloworld.pyx:3:6: 'Decimal' is not a type identifier
Error compiling Cython file:
------------------------------------------------------------
...
from decimal cimport Decimal
cpdef Decimal to_decimal(str value):
return Decimal(value)
^
------------------------------------------------------------
helloworld.pyx:4:11: 'Decimal' is not a constant, variable or function identifier

我知道Decimal类是从这个c扩展文件创建的https://github.com/python/cpython/blob/master/Modules/_decimal/_decimal.c.因此,它似乎应该在cython代码中可用。有人知道怎么做吗?

您指的是标准库模块decimal吗?

如果是这样,就不能使用cimport Decimal,因为它不是pxd文件中声明的cython扩展类型(就像C头一样(。此外,由于同样的原因,您不能将函数返回值键入为Decimal。事实上,Decimal是在C中实现的,但它不是cython扩展类型,或者cython目前还没有内置支持它作为类型标识符。

你想做的事情看起来像:

class Foo:
pass
cpdef Foo func():   # the same compile error
pass

然而,以下工作:

cdef class Foo:
pass
cpdef Foo func():
pass

总之,您可以使用cdef class作为类型标识符,而不是纯粹的python类。您可以修改您的代码,如:

from decimal import Decimal
cpdef to_decimal(str value):
return Decimal(value)

您可能想知道为什么这样做:cdef list my_list = [],因为list不是cdef class。好吧,cython有built-in支持!

您可能还对cython提供的标准标头感兴趣,通常在site-packages/Cython/Includes中,请务必查看cpython子文件夹。

gmpy2导出可在Cython代码中使用的本机API。

提供的最小示例是用C风格的cython代码编写的,所以您的代码可读性会降低。或者,您可以用Cython编写自己惯用的OOP包装器。

如果这样的包装已经存在,请纠正我。

最新更新