Estoy usando Cython para envolver una biblioteca C. El archivo de encabezado de la biblioteca C define una serie de constantes, por lo que en mi módulo cython, tengo algo como:
cdef extern from "lib.h": cdef int CONST_A = 0 cdef int CONST_B = 1Cuando compilo la extensión, las constantes no están disponibles en Python. Intenté hacer algo como esto, pero no parecía funcionar:
cdef extern from "lib.h": cdef int CONST_A = 0 cdef int CONST_B = 1 CONST_A = CONST_A CONST_B = CONST_B¿Alguna idea sobre cómo hacer que estas constantes estén disponibles en Python?
Tienes razón en que parece haber un agujero en Cython allí.
Puedo declarar cpdef int CONST_C = 3 y compila pero no es visible desde Python. Eso parecería ser un error: si acepta la sintaxis, debería hacer algo razonable con ella.
Una cosa que parece funcionar es esta:
cpdef enum: CONST_A = 0 CONST_B = 1Eso puede o no ser lo suficientemente bueno para su caso, pero parece que funcionaría bien para muchos casos de uso, ¿tal vez es por eso que no se notó el error?
La solución que uso, que sería bastante fácil de cambiar a la solución "correcta" una vez admitida, es volver a declarar los valores de la enumeración uno por uno en el archivo .pyx con el prefijo del nombre de la enumeración, luego son bastante fáciles de detectar.
Entonces en foo.pxd:
cdef enum Mood: happy sadLuego, en foo.pyx en el ámbito global:
Mood_happy = happy Mood_sad = sadY en bar.py:
from foo import Mood_happy, Mood_sad # do something with Mood_happy and Mood_sad as intsComentario demasiado tarde, pero ¿qué tal el siguiente código? Esta idea se deriva de ¿Cómo se puede exponer un valor de C #definido a Python en un módulo de Cython?
Esta solución funciona bien en mi biblioteca. "CONST_A" y "CONST_B" son alias para las funciones cdef/cpdef. En Cython (.pyx), se pueden usar como una macro. Para exponer la macro a Python, se necesitan CONST_A = _CONST_A y CONST_B = _CONST_B.
a.pyx
cdef extern from "lib.h": cdef int _CONST_A "CONST_A" cdef int _CONST_B "CONST_B" def use_const(): if CONST_A: do_something() if CONST_B: do_something() CONST_A = _CONST_A CONST_B = _CONST_BDespués de compilar, puede usarlos en código python.
use_a.py
import a print(a.CONST_A) print(a.CONST_B)