gpt4 book ai didi

python - cython 中的异常处理

转载 作者:行者123 更新时间:2023-12-05 01:33:42 24 4
gpt4 key购买 nike

我有两个 .pyx 文件 - bar.pyxbaz.pyx。我想将它们组合成一个 .so 文件。

baz.pyx 中我有一个函数 baz 应该做一些检查并在出现问题时引发异常。在 bar.pyx 中,我想调用 baz() 并期望通过打印回溯来引发异常。

不幸的是,无论我尝试什么,我都会遇到一些其他的运行时错误。

setup.py 中的扩展

[
Extension(
'testlib.baz', ['src/testlib/baz.pyx'],
),
Extension(
'testlib.foo', ['src/testlib/bar.pyx', 'src/testlib/baz.c'],
),
]

如何测试

import testlib.foo
testlib.foo.foo_baz()

变体 1

# baz.pyx

cdef public baz():
raise ValueError

# bar.pyx

cdef extern baz()

def foo_baz():
baz() # Segmentation fault

变体 2

# baz.pyx

cdef public int baz() except -1:
PyErr_SetNone(ValueError)
return -1

# bar.pyx

cdef extern int baz() except -1

def foo_baz():
baz() # SystemError: <built-in function foo_baz> returned NULL without setting an error

我可以从 baz 返回一些值并根据返回值在 foo_baz 中引发异常,但我希望在 bar 中出现最少的逻辑。 pyx.

# baz.pyx

cdef public int baz():
return -1

# bar.pyx

cdef extern int baz()

def foo_baz():
if baz() == -1:
raise ValueError # OK

最佳答案

进一步扩展我的评论:导入模块时,Cython 做了很多工作,设置 C 全局变量,使其能够完全访问 C 内置类型(包括异常)、字符串常量和一些其他事情。在这种情况下,该行被翻译成

__Pyx_Raise(__pyx_builtin_ValueError, 0, 0, 0);

如果 __pyx_builtin_ValueError 没有初始化,那么一切都会出错。

结果是 Cython 代码(甚至是 public Cython 代码)实际上并不是独立的,而是模块的一部分,并且它确实依赖于被调用的模块 init 函数才能工作。在您的情况下,它在引发异常时失败了,但是如果您克服了这一点,就会有一系列类似的错误等待发生。


作为一般规则,我建议不要将多个模块链接到一个 .so 文件中。但是它可以工作;见https://stackoverflow.com/a/52714500/4657412一个食谱。如您所见,它非常复杂,需要对 C API 导入过程有一些了解。


其他选项(不涉及自己用 C 编写代码)是使用多个模块和 cimport 机制在它们之间共享实现,或者可能是 the older "include" mechanism通常不推荐这样做,但有时会很方便。

关于python - cython 中的异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64479504/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com