- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个 .pyx 文件,我在其中定义了一些函数,例如
cdef double foo(double a) nogil:
return 3. * a
我如何在 pyx 文件之外对此类函数的行为进行单元测试?由于它们是 cdef,我无法简单地导入它们...
最佳答案
要测试 cdef
功能,您需要在 Cython 中编写测试。可以尝试使用 cpdef
函数,但并非所有签名都可以在这种情况下使用(例如使用指针的签名,如 int *
、float *
等等)。
要访问 cdef 函数,您需要通过 pxd 文件“导出”它们(对于 cdef-functions of extension types 也可以这样做):
#my_module.pyx:
cdef double foo(double a) nogil:
return 3. * a
#my_module.pxd:
cdef double foo(double a) nogil
现在可以在 Cython 测试器中导入和测试功能:
#test_my_module.pyx
cimport my_module
def test_foo():
assert my_module.foo(2.0)==6.0
print("test ok")
test_foo()
现在
>>> cythonize -i my_module.pyx
>>> cythonize -i test_my_module.pyx
>>> python -c "import test_my_module"
test ok
从那里去哪里取决于您的测试基础设施。
例如,如果您使用 unittest
-module,那么您可以使用 pyximport 来 cythonize/load test-module 检查它并将所有测试用例转换为 unittest
-test例或直接在您的 cython 代码中使用 unittest
(可能是更好的解决方案)。
这是 unittest
的概念证明:
#test_my_module.pyx
cimport my_module
import unittest
class CyTester(unittest.TestCase):
def test_foo(self):
self.assertEqual(my_module.foo(2.0),6.0)
现在我们只需要在纯 python 中翻译和导入它就可以对其进行unittest
:
#test_cy.py
import pyximport;
pyximport.install(setup_args = {"script_args" : ["--force"]},
language_level=3)
# now drag CyTester into the global namespace,
# so tests can be discovered by unittest
from test_my_module import *
现在:
>>> python -m unittest test_cy.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
顺便说一句,不需要显式地对 pyx 模块进行 cythonize - pyximport
会自动为我们完成。
警告:pyximport
将 cythonized c 文件缓存在 ~/.pyxbld
(或其他操作系统上的类似文件)中,只要因为 test_my_module.pyx
没有改变,扩展不会重建,即使它的依赖关系发生了变化。这可能是一个问题(除其他外),当 my_module
更改并导致二进制不兼容时(幸运的是,如果是这种情况,python 会发出警告)。
通过传递 setup_args = {"script_args": ["--force"]}
我们强制重建。
另一种选择是删除缓存文件(可以使用临时目录,例如使用 tempfile.TemporaryDirectory()
创建,通过 pyximport.install(build_dir=...)
),这具有保持系统清洁的优点。
需要明确的 language_level
( what is language_level
? ) 以防止警告。
如果您使用虚拟环境并通过 setup.py
(或类似的工作流程)安装 cython-package,您需要 to make sure that *.pxd
files are also included into installation ,即您的安装文件需要增加:
from setuptools import setup, find_packages, Extension
# usual stuff for cython-modules here
...
kwargs = {
# usual stuff for cython-modules here
...
#ensure pxd-files:
'package_data' : { 'my_module': ['*.pxd']},
'include_package_data' : True,
'zip_safe' : False #needed because setuptools are used
}
setup(**kwargs)
关于python - 如何在 Cython 中测试 cdef 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42259741/
在不牺牲 cdef 调用程序中的 cdef 的情况下,他们有什么方法可以使这项工作正常进行吗? (也没有使用 cpdef) from array import * from numpy import
我正在学习 Cython,现在正在试验它。我尝试了基本的 cdef 类示例程序,它运行良好。 现在我想做的是在 cdef 类类型中混合使用 cdef 和非 cdef 属性,就像这样 cdef clas
我正在尝试在 cython 中实现通用排序算法。因此,我创建了以下模块,它在 sorter_t 类中实现了 Heapsort 算法: # file general_sort_c.pyx from li
我想要一个 cdef 类的 cython 数组: cdef class Child: cdef int i def do(self): self.i += 1 cdef
当我声明一个返回 double 的 cdef 函数时,我会写 cdef double method_name(...) 。如果它没有返回任何东西并且我只是将它省略给 cdef method_name(
我在同一个模块的所有函数中使用了很多相同类型的变量: def func1(double x): cdef double a,b,c a = x b = x**2 c =
我有一个使用许多 nogil cdef 函数的应用程序,我想对它们进行分析为了找到瓶颈。 我尝试将 profile=True 指令传递给 Cython,但这些函数似乎是免疫的,因此 cProfile.
感谢 stackoverflow 上的一些人,我终于让 cython 工作了,但现在有一个问题。从我不使用 cdef 到我使用 cdef 确实没有速度提升。不要误会我的意思,当我使用 cython 编
关于像这样应用于 cdef extern 的“nogil”,有一件事我不完全理解: cdef extern from "pthread.h" nogil: ctypedef struct pt
我想要一个 cdef 类的 cython 数组: cdef class Child: cdef int i def do(self): self.i += 1 cdef
我想知道在声明函数时def、cdef 和cpdef 之间的区别。def 和其他 def 之间的区别或多或少是清楚的。而且我还看到,有时它会在声明中添加返回类型 (cdef void/double/in
我正在尝试在运行 Alpine 的 Docker 镜像上编译一些代码。但是,gcc 由于 fatal error: sys/cdefs.h: No such file or directory 而不断
常设问题: 为什么 Cython 编译中的其他错误指向特定的错误行,而这个却没有? 更新前: 由于难以编译扩展类型,正如下面“不会编译”链接中所引用的,人们认为 AssertionError 与扩展类
是否有一种 cython-ic 方法可以将 cdef 数组设置为零。我有一个具有以下签名的函数: cdef cget_values(double[:] cpc_x, double[:] cpc_y):
我正在尝试改进此使用列表类型的代码: # CLASS ORDERC # ################ cdef class OrderC: cdef int _side cdef
我很好奇以下内容是否有效,其中只有部分变量在类型声明的类中进行了类型声明。也就是说,在这种情况下,类之前的 cdef 会无效吗? cdef class CythonClass: cdef in
我有一个 cdef 函数返回一个 (int, int) 元组。我需要传播异常,因此必须为异常指定返回类型。由于我的函数从不返回负值,这可能例如是 (-1, -1)。使用 documentation 中
class Myuser * MyClient_GetMyUser(AUser aUser); 这是尝试使用 ffi.cdef 声明该函数的错误: Error: dllImport.lua:861:
尝试使用 XCode 在 Mac Lion (10.7) 上编译我的 C++ 应用程序时,我一直遇到错误。编译器提示 cdefs.h 中的一行(包含在 syslog.h 中)带有错误 expected
我已经使用 cdef 定义了一个 python 类,它用 Cython 包装了一个 C++ 类并且它工作正常。但是,当我在 python 或类中使用 help(class) 时?在 ipython 中
我是一名优秀的程序员,十分优秀!