2017-10-06 104 views
0

我試圖構建一個使用python和cython模塊的包。在構建和安裝之後,我遇到了導入問題,我不確定如何從構建過程生成的.so文件中導入文件。使用cython擴展打包python

之前建設我的文件夾結構看起來像這樣

root/ 
├── c_integrate.c 
├── c_integrate.pyx 
├── cython_builder.py 
├── __init__.py 
├── integrator_class.py 
├── integrator_modules 
│   ├── cython_integrator.py 
│   ├── __init__.py 
│   ├── integrator.py 
│   ├── numba_integrator.py 
│   ├── numpy_integrator.py 
│   ├── quadratic_error.png 
│   ├── report3.txt 
│   ├── report4.txt 
│   └── report5.txt 
├── report6.txt 
├── setup.py 
└── test 
    ├── __init__.py 
    └── test_integrator.py 

樓內有python3.5 setup.py build給出root

root/build/ 
├── lib.linux-x86_64-3.5 
│   ├── c_integrate.cpython-35m-x86_64-linux-gnu.so 
│   ├── integrator_modules 
│   │   ├── cython_integrator.py 
│   │   ├── __init__.py 
│   │   ├── integrator.py 
│   │   ├── numba_integrator.py 
│   │   └── numpy_integrator.py 
│   └── test 
│    ├── __init__.py 
│    └── test_integrator.py 

這個新的文件夾中的setup.py文件看起來像這樣

from setuptools import setup, Extension, find_packages 
import numpy 

setup(
    name = "integrator_package", 
    author = "foo", 
    packages = find_packages(), 
    ext_modules = [Extension("c_integrate", ["c_integrate.c"])], 
    include_dirs=[numpy.get_include()], 
) 

我的問題那麼:怎麼做我將.so文件中的函數的輸入語句寫入位於build目錄中的rootcython_integratortest_integrator中的ìntegrator_class.py。追加到sys.path似乎是一個我不太喜歡的快速和骯髒的解決方案。

編輯: 正如在評論中指出,我還沒有安裝軟件包。這是因爲我不知道寫什麼.so文件

+1

是[this](https://stackoverflow.com/questions/19048732/python-setup-py-develop-vs-install)有關嗎? – DavidW

+0

好像你沒有像@DavidW指出的那樣安裝你製作的軟件包。發出'pip安裝路徑/ to/root /'或'pip install --editable = path/to/root /'來與使用python建立的文件結婚。 – hoefling

+0

是的,我沒有安裝它 - 但我的問題是,因爲'.so'文件被命名爲特定於平臺,我不知道如何導入它。特別是因爲'lib.linux ...'文件夾沒有'__init __。py'文件。有意思的是:在我安裝後,只是嘗試重命名'.so'文件並導入它引發'SystemError:父模塊''未加載,不能執行相對導入 ' – Copperwire

回答

0

導入在沒有特定的順序:

  1. 文件setup.py通常低於的根源所在項目。例如:

    library_name/ 
        __init__.py 
        file1.py 
    setup.py 
    README 
    
  2. 然後,構建目錄一起出現在項目源代碼,而不是在項目源。

  3. 要在Python中導入文件c_integrate.cpython-35m-x86_64-linux-gnu.so,只需導入「c_integrate」即可。其餘的命名自動處理,因爲它只是平臺信息。見PEP 3149

  4. 有效模塊的

    1. modulename/__init__.py文件的目錄一個
    2. 名爲modulename.py
    3. 文件名爲modulename.PLATFORMINFO.so
    當然

    位於文件Python路徑。因此,編譯的Cython模塊不需要__init__.py文件。

    您的具體情況,將用Cython代碼項目目錄,要麼使用相對導入import .c_integrate或完整from integrator_modules import c_integrate在當你的包是安裝後者只適用。

少數的這些信息都可以在我的博客文章上用Cython模塊http://pdebuyl.be/blog/2017/cython-module.html

我認爲,這應該讓你建立一個適當的包裝,如果沒有下面評論被發現。

編輯:完成配置(見下文評論),海報也

  1. 固定在setup.py文件模塊路徑,以便它是完整的模塊名稱從PYTHONPATH開始:Extension("integrator_package.integrator_modules.c_integrat‌​or", ["integrator_package/integrator_modules/c_integrator.c"]代替的Extension("c_integrate", ["c_integrate.c"])]
  2. Cythonize模塊,構建它並使用相同的Python解釋器。

更多評論:setup.py文件也可以對文件進行cython化。作爲源包括.pyx文件而不是.c文件。

cythonize(Extension('integrator_package.integrator_modules.c_integrat‌​or', 
      ["integrator_package/integrator_modules/c_integrator.pyx"], 
      include_dirs=[numpy.get_include()])) 
+0

非常感謝您的答案!我對樹進行了修改,看起來像你所建議的。我現在在導入cython模塊'ImportError:動態模塊沒有定義模塊導出函數(PyInit_c_integrator)'''時出錯。安裝文件建立擴展爲'ext_modules = [擴展( 「integrator_package.integrator_modules.c_integrator」, \t \t \t \t [ 「integrator_package/integrator_modules/c_integrator.c」]' – Copperwire

+0

從[此答案解決](HTTPS://cypressoverflow.com/questions/36723206/cython-compilation-error-dynamic-module-does-not-define-module-export-function)thread。原來'cython'是build敏感的 – Copperwire