在 Cython 中定义字符串数组

Define array of strings in Cython

卡在一些基本的 Cython 上 - 在 Cython 中定义字符串数组的规范和有效的方法是什么?具体来说,我想定义一个固定长度的常量数组char 个。 (请注意,此时我不想引入 NumPy。)

在 C 中,这将是:

/* 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

你需要两行:

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

有点违反直觉的是将 unicode 字符串 (Python3!) 分配给 char*。这是 Cython 的怪癖之一。另一方面,在仅使用一个值初始化所有内容时,需要字节对象:

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

另一种选择是以下单行:

%%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_headerschar ** 类型,缺点是 print(headers) 不再开箱即用。

对于python3 Unicode字符串,这是可以的-

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

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