Как я могу использовать десятичный объект Python в коде Cython? - PullRequest
1 голос
/ 30 марта 2020

Наивно я пытаюсь

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

Я знаю, что десятичный класс создан из этого файла расширения c https://github.com/python/cpython/blob/master/Modules/_decimal/_decimal.c. Таким образом, кажется, что это должно быть использовано в коде Cython. Кто-нибудь знает как?

1 Ответ

1 голос
/ 30 марта 2020

Вы имеете в виду стандартный библиотечный модуль decimal?

Если это так, вы не можете cimport Decimal, поскольку это не тип расширения Cython , объявленный в файле pxd (например, заголовок 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.

...