Определить массив строк в Cython - PullRequest
0 голосов
/ 01 декабря 2018

Застрял на каком-то базовом Cython здесь - Каков канонический и эффективный способ определения массива строк в Cython? В частности, я хочу определить постоянный массив фиксированной длины, равный char.(Обратите внимание, что я бы предпочел не вводить NumPy на этом этапе.)

В Си это будет:

/* cletters.c */
#include <stdio.h>

int main(void)
{
    const char *headers[3] = {"to", "from", "sender"};
    int i;
    for (i = 0; i < 3; i++)
        printf("%s\n", headers[i]);
}

Попытка в Cython:

# cython: language_level=3
# letters.pyx

cpdef main():
    cdef const char *headers[3] = {"to", "from", "sender"}
    print(headers)

Однако это дает:

(cy) $ python3 ./setup.py build_ext --inplace --quiet
cpdef main():
    cdef const char *headers[3] = {"to", "from", "sender"}
                               ^
------------------------------------------------------------

letters.pyx:5:32: Syntax error in C variable declaration

Ответы [ 2 ]

0 голосов
/ 30 июля 2019

Для строк Python3 Unicode это возможно -

cdef Py_UNICODE* x[2] 
x = ["hello", "worlᏪd"]

или

cdef Py_UNICODE** x
x = ["hello", "worlᏪd"]
0 голосов
/ 01 декабря 2018

Вам нужно две строки:

%%cython
cpdef main():
    cdef const char *headers[3] 
    headers[:] = ['to','from','sender`]       
    print(headers)

Несколько нелогично, чем присваивать строки юникода (Python3!) Для char*.Это одна из причуд Cython.С другой стороны, при инициализации всего лишь одним значением необходим объект bytes:

%%cython
cpdef main():
    cdef const char *headers[3] 
    headers[:] = b'init_value`  ## unicode-string 'init_value' doesn't work.     
    print(headers)

Другой альтернативой является следующий oneliner:

%%cython
cpdef main():
    cdef const char **headers=['to','from','sender`]

    print(headers[0], headers[1], headers[2])

, который не являетсяточно так же, как указано выше, и приводит к следующему C-коду:

  char const **__pyx_v_headers;
  ...
  char const *__pyx_t_1[3];
  ...
  __pyx_t_1[0] = ((char const *)"to");
  __pyx_t_1[1] = ((char const *)"from");
  __pyx_t_1[2] = ((char const *)"sender");
  __pyx_v_headers = __pyx_t_1;

__pyx_v_headers относится к типу char **, а недостатком является то, что print(headers) больше не работает из коробки.

...