【问题标题】:How should I use the `round() ` function in Cython?我应该如何在 Cython 中使用 `round()` 函数?
【发布时间】:2014-07-14 00:39:38
【问题描述】:

---------更新--------------

发现了一些亮光here

这样做的缺点是官方的 64 位 Python 版本不附带 libmsvcr90.a,我们需要将其链接到正确的 C 运行时 DLL。

-----------原帖-------

我的 Python 版本:

Python 3.3.5,在 Windows 中带有 MSC v.1600 64 位。已安装并使用 Windows SDK v7.1。我已经使用 Cython 一个星期了,它似乎可以很好地运行其他代码。

在这个link 中,它说round() 是内置函数之一。但是,当我在我的cython代码中调用它并使用cython my_code.pyx -a检查时,该函数是纯黄色的,这意味着使用了python方法。

然后我做了一些谷歌搜索,并使用了:

from libc.math cimport round

但它在编译期间显示“未解析的外部符号”。

我该怎么办?

代码如下:

from libc.math cimport round

cdef float a = 1.5
cdef float b

b = round(a)
print(b)

它说:致命错误 LNK1120: 1 unresolved externals error

我的 setup.py:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import numpy as np

extensions = [
    Extension('test', ['test.pyx'], include_dirs = [np.get_include()]),
    ]

setup(
    ext_modules = cythonize(extensions)
    )

我知道在这种情况下 np.get_include() 确实没有必要,但我只是添加了它们,因为我经常使用 numpy 并且无论如何它不会对这种情况造成太大伤害。

我的编译命令:

python setup.py build_ext --inplace

结果(我实际上在我的机器上使用了 setup1.py):

X:\WorkFolder\DataAnalysis\lw9pg\mol>python setup1.py build_ext --inplace 运行 build_ext
构建“测试”扩展
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\Bin\amd64\cl.exe /c /nologo /Ox /MD /W3 /GS- /DNDEBUG -IX:\WinPython3\python-3.3.5。 amd64\include -IX:\WinPython3\python-3.3.5.amd64\include /Tctest.c /Fobuild\temp.win-amd64-3.3\Release\test.obj
测试.c
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\Bin\amd64\link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:X:\WinPython3\python-3.3.5.amd64\libs LIBPATH: X:\WinPython3\python-3.3.5.amd64\PCbuild\amd64 /EXPORT:PyInit_test build\temp.win -amd64-3.3\Release\test.obj /OUT:X:\WorkFolder\DataAnalysis\lw9pg\mol\test.pyd /IMPLIB:build\temp.win-amd64-3.3\Release\
test.lib /MANIFESTFILE:build\temp.win-amd64-3.3\Release\test.pyd.manifest
test.obj : 警告 LNK4197: export 'PyInit_test' 指定了多次;使用第一个规范
创建库 build\temp.win-amd64-3.3\Release\test.lib 和对象 build\temp.win-amd64-3.3\Release\test.exp
test.obj:错误 LNK2019:函数 __pyx_pf_4test_rounding
中引用的未解析的外部符号轮回 X:\WorkFolder\DataAnalysis\lw9pg\mol\test.pyd:致命错误 LNK1120:1 个未解决的外部问题
错误:命令 '"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\Bin\amd64\link.exe"' 失败,退出状态为 112
0

【问题讨论】:

  • 你是如何使用它的?
  • @PadraicCunningham 感谢您的回复!我会在一分钟内发布我的代码。我忘了这样做......对不起。
  • 所以你正在编译你发布的内容?
  • @PadraicCunningham 是的,我是。但我还没有尝试过 ipython 魔法。
  • 我不确定问题出在哪里:您链接的文档确实说round 可用,但同一篇文章说enumerateslice 也可用。说命名空间中有内置函数与有 C 版本不同。

标签: python cython


【解决方案1】:

如果你想测试简单的cython代码,最简单的方法是使用pyximport

要运行你的,假设你的代码所在的文件名为tester.pyx

在同一目录中,将其放在 python 文件的顶部并运行该文件,您将看到您的print b 将输出2.0

import pyximport
pyximport.install()

为了编译和运行一个 cython 函数,我使用了以下 setup.py 脚本:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext= Extension("tester", sources=["tester.pyx"])
setup(ext_modules=[ext],cmdclass={'build_ext': build_ext})

使用以下命令在您的.pyx 文件上运行它,--inplace 会将其编译到相同的目录中:

python setup.py build_ext --inplace --compiler=mingw32 # --compiler=mingw32 only needed on windows

您将拥有一个 (tester.pyd)(mac 和 linux 上的 tester.so)文件,您可以从中导入您的函数,就好像它们来自 python 模块一样。

这是一个对数字进行四舍五入的简单函数:

from libc.math cimport round

def rounding(float n):
    return round(n)

compile 它或使用 pyxinstall 导入它并像这样运行它:

In [29]: from tester1 import *

In [30]: rounding(12.3453455)
Out[30]: 12.0

使用 pyximport:

In [21]: import pyximport

In [22]: pyximport.install()
Out[22]: (None, None)
         from tester import *
In [23]: rounding(10.23232)
Out[23]: 10.0

我创建了一个纯python的舍入方法来比较:

def py_rounding(n):
    return round(n)

import timeit
if __name__=='__main__':
    print timeit.timeit('py_rounding(10.23232)','from cyt import py_rounding')
    print timeit.timeit('rounding(10.23232)','from tester import rounding')
    0.183354854584
    0.037761926651

cython 代码要快得多。

这些是非常基本的示例,您可以找到 cython here 的更好用途 包括使用 %load_ext cythonmagic 使用 ipython

【讨论】:

  • 谢谢帕德莱克!我确实知道如何编译 Cython,您的回答似乎表明上述代码可以在您的 Python 上顺利编译……是这样吗?我认为这可能与 Windows 7 上的 Python 3 和 64 位有关。我在 OP 上附加了 setup.py。
  • 您的代码使用我的 setup.py 脚本使用 python2.7 和 3.4 对我来说编译得很好,您是否尝试过使用我的脚本或--complier=mingw32,我的印象是 Windows 需要它?
  • 使用你的 setup.py 也可以很好地编译
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-03
  • 2017-10-23
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
  • 2015-03-17
相关资源
最近更新 更多