Cython:导入.pyd文件会返回错误(缺少init函数?)

时间:2017-06-27 17:58:18

标签: python cython cythonize

我正在学习如何使用Cython有效地编译Python代码并使其更快。

这是我到目前为止所做的:

  1. 我创建了一个名为math_code_python.py的Python文件,并在其中放入了4个简单的函数。
  2. 我将该文件保存为math_code_cython.pyx
  3. 我创建了一个名为setup.py的设置文件。
  4. 我在python C:\Users\loic\Documents\math_code\setup.py build_ext --inplace
  5. 中输入了Command Prompt
  6. 我收到了一个名为math_code_cython.cp36-win_amd64.pyd的已编译文件,我将其重命名为math_code_pyd.pyd
  7. 最后,我创建了一个名为test_math_code.pyd的Python文件,其中只有import math_code_pyd。当我执行这个文件时,我收到了这条消息:

    ImportError: dynamic module does not define module export function
    
  8. 我做了一些研究,感谢那些帖子我理解我必须提供init function

    我的问题是:我该怎么做?我是否必须在math_code_python.py末尾添加一个函数,如下所示?

    def __init__(self):
        # something ?
    

    我的Python版本:

    Python 3.6.1 |Anaconda 4.4.0 (64-bit)| (default, May 11 2017, 13:25:24) [MSC v.1900 64 bit (AMD64)]
    

    math_code_python.py

    def fact(n):
        if n==0 or n==1:
            return 1
        else:
            return n*fact(n-1)
    
    def fibo(n):
        if n==0 or n==1:
            return 1
        else:
            return fibo(n-1)+fibo(n-2)
    
    def dicho(f, a, b, eps):
        assert f(a)*f(b) < 0
        while b-a > eps:
            M = (a+b)/2.
            if f(a) * f(M) > 0:
                a = M
            else:
                b = M
        return M
    
    def newton(f, fp, x0, eps):
        u = x0
        v = u - f(u)/fp(u)
        while abs(v-u) > eps:
            u = v
            v = u - f(u)/fp(u)
        return v
    

    setup.py

    try:
        from setuptools import setup
    except ImportError:
        from distutils.core import setup
    
    from Cython.Distutils import build_ext
    from Cython.Build import cythonize
    
    import numpy as np
    
    setup(name = "maido",
          include_dirs = [np.get_include()],
          cmdclass = {'build_ext': build_ext},
          ext_modules = cythonize(r"C:\Users\loic\Documents\math_code\math_code_cython.pyx"),
          )
    

1 个答案:

答案 0 :(得分:1)

您的错误是重命名pyd文件。当您致电import math_code_pyd时,它会专门查找initmath_code_pyd(Python2)或PyInit_math_code_pyd(Python3)。

当您使用Cython编译它时,它会生成一个与.pyx文件名匹配的函数(即initmath_code_cythonPyInit_math_code_cython)。因此,它没有找到它期望的功能。 您不必自己提供此功能--Cython会生成它。

只需将.pyx文件命名为您希望调用模块的内容,并且不要重命名.pyd文件。 (原则上你可以删除.cp36-win_amd64但它有用并且有一个原因。)