我应该如何在Cython中使用`round()`函数?

时间:2014-05-24 21:26:17

标签: python cython

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

发现了一些光here

  

这方面的缺点是官方的64位Python版本没有附带libmsvcr90.a,我们需要将它与正确的C运行时DLL链接。

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

我的Python版本:

Python 3.3.5,Windows中的64位MSC v.1600。已安装并使用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未解决的外部错误

我的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
test.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和object build \ temp.win-amd64-3.3 \ Release \ test.exp
test.obj:错误LNK2019:函数__pyx_pf_4test_rounding中引用的未解析的外部符号round 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

1 个答案:

答案 0 :(得分:3)

如果您想测试简单的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