在Python文件Pycharm中导入Cython类

时间:2016-04-03 02:54:40

标签: python pycharm cython

如何在pycharm python文件中导入已编译的cython文件?

这是我的设置。

从我的项目根目录,cython类是“/classes/knn.cpython-35m-x86_64-linux-gnu.so”。我的python文件是“/classes/testing_cython_knn.py”。

我在“/ classes /”...

中有一个“__init __.py”文件

但是,Pycharm无法将“.so”文件识别为可以导入的文件。为了使这个文件可以导入,我需要做什么,所以我可以测试它?

目前,我已经在常规的基于终端的python中成功编译并导入了一个“helloworld.so”文件......但是,我定义的函数是pythonic函数......没有C-stuff。

我的Cythonic文件是:

import numpy as np
cimport numpy as np


from scipy.stats import mode
from scipy.spatial.distance import cdist
from threading import Thread



cdef class KNN:
    cdef public int k
    cdef public str metric
    cdef public np.ndarray trainingX
    cdef public np.ndarray trainingY
    cdef public np.ndarray predict(self,np.ndarray X):
        cdef np.ndarray distances,predicted_classes,sorted_distance_indices

        distances = cdist(X,self.trainingX,metric=self.metric)
        predicted_classes = np.zeros(X.shape[0],dtype=np.float64)
        sorted_distance_indices = np.argpartition(distances,self.k,axis=1)[:,:self.k]
        predicted_classes,_ = mode(self.trainingY[sorted_distance_indices])
        return predicted_classes

和setup.py:

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


extensions = [
    Extension("knn",["cKNN.pyx"]),
    Extension("*",["*.pyx"],include_dirs=[numpy.get_include()])]

setup(ext_modules = cythonize(extensions),include_dirs=[numpy.get_include()])

目前,在使用导入错误导入到运行在终端上的python时失败:

  

动态模块没有定义模块导出功能(PyInit_knn)

1 个答案:

答案 0 :(得分:3)

我注意到的第一件事是您正在重命名您的扩展程序。对于Cython,扩展名必须与要编译的文件的名称相对应。那应该解决

  

动态模块没有定义模块导出功能(PyInit_knn)

其次,你宣布两个扩展,但你只有一个文件(需要Numpy)所以你应该完全删除第一个扩展名(*将处理文件夹中的所有.pyx文件)或删除第二个并将'include_dirs'指令集成到第一个扩展名,因此您应该将扩展名列表更改为:

extensions = [
    Extension("cKNN",["cKNN.pyx"],include_dirs=[numpy.get_include()])]

如果您使用--inplace或将.so文件移动到正确的位置,它将被导入。 Pycharm没有任何关系,它完全取决于Cpython,但是,在你的setup.py中,你必须小心正确设置路径。如果项目的文件夹结构如下:

- knnProject (this opens in Pycharm) 
- - knnextension
- - - classes
- - - - __init__.py
- - - - cKNN.pyx
- - - __init__.py (this is required to do module import from /classes)
- - setup.py
- - test.py

您的分机应该说:

extensions = [
        Extension("knnextension/classes/cKNN",["knnextension/classes/cKNN.pyx"],include_dirs=[numpy.get_include()])]

共享库文件(.so或.pyd)将在/ classes中显示(通过使用--inplace)。在classes/__init__.py文件中,您可以使用以下内容导入类:

from .cKNN import KNN

然后从test.py:

from knnextension.classes import KNN

检查其他正在运行的cython扩展like my own,看看结构如何(也使用Numpy)。