[英]Export constants from header with Cython
I'm using Cython to wrap a C library. 我正在使用Cython来包装C库。 The C library's header file defines a number of constants, so in my cython module, I have something like:
C库的头文件定义了许多常量,所以在我的cython模块中,我有类似的东西:
cdef extern from "lib.h":
cdef int CONST_A = 0
cdef int CONST_B = 1
When I compile the extension, the constants are not available in Python. 当我编译扩展时,常量在Python中不可用。 I tried doing something like this, but it did not seem to work:
我尝试过这样的事情,但似乎没有用:
cdef extern from "lib.h":
cdef int CONST_A = 0
cdef int CONST_B = 1
CONST_A = CONST_A
CONST_B = CONST_B
Any ideas on how to make these constants available in Python? 关于如何在Python中提供这些常量的任何想法?
You're right in that there seems to be a hole in Cython there. 你是对的,那里似乎有一个洞在Cython那里。
I can declare cpdef int CONST_C = 3
and it compiles but isn't visible from Python. 我可以声明
cpdef int CONST_C = 3
并且它编译但是从Python cpdef int CONST_C = 3
不到。 That would seem to be a bug -- if it accepts the syntax, it should do something reasonable with it. 这似乎是一个错误 - 如果它接受语法,它应该做一些合理的事情。
One thing that did seem to work is this: 似乎有用的一件事是:
cpdef enum:
CONST_A = 0
CONST_B = 1
That may or may not be good enough for your case, but it seems it would work well for many use-cases -- maybe it's why the bug wasn't noticed? 对于你的情况,这可能或者可能不够好,但似乎它适用于许多用例 - 也许这就是为什么没有注意到这个bug?
The solution I use which would be fairly easy to then switch to the "right" solution once supported is to re-declare the enum values one by one in the .pyx file prefixed by the enum's name, then they are quite easy to spot. 我使用的解决方案一旦支持就很容易切换到“正确”的解决方案是在.pyx文件中逐个重新声明枚举值,前缀为enum的名称,然后它们很容易被发现。
So in foo.pxd: 所以在foo.pxd中:
cdef enum Mood:
happy
sad
Then in foo.pyx at global scope: 然后在全局范围的foo.pyx中:
Mood_happy = happy
Mood_sad = sad
And in bar.py: 并在bar.py:
from foo import Mood_happy, Mood_sad
# do something with Mood_happy and Mood_sad as ints
Too late comment but how about the following code ? 评论太迟了但是下面的代码怎么样? This idea is derived from How can a #defined C value be exposed to Python in a Cython module?
这个想法来自于如何在Cython模块中将#defined C值暴露给Python?
This solution works well in my library. 此解决方案在我的库中运行良好。 "CONST_A" and "CONST_B" are alias for cdef/cpdef functions.
“CONST_A”和“CONST_B”是cdef / cpdef函数的别名。 In of Cython(.pyx), they can be used as a macro.
在Cython(.pyx)中,它们可以用作宏。 To expose macro to Python, CONST_A = _CONST_A and CONST_B = _CONST_B are needed.
要将宏公开给Python,需要CONST_A = _CONST_A和CONST_B = _CONST_B。
a.pyx 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_B
After compile, you can use them in python code. 编译后,您可以在python代码中使用它们。
use_a.py use_a.py
import a
print(a.CONST_A)
print(a.CONST_B)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.