kesalahan impor cython dalam paket yang sama

Saya telah melihat pertanyaan ini dan jawabannya sepertinya tidak berhasil. Berikut adalah struktur direktori saya.

.
├── my_package
│   ├── a.pyx
│   ├── b.pyx
│   ├── b.pxd
│   ├── test.py
│   └── __init__.py
└── setup.py

file a.pyx

cimport my_package.b  as b

class a:
    def __init__(self):
        self.b = b.b()
        self.b.run()

file b.pyx

cdef class b:

    def __init__(self):
        pass

    cpdef run(self):
        print "b is running"

file b.pxd

cdef class b:
    cpdef run(self)

tes.py

import a

c = a.a()

setup.py

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

extensions = [
    Extension("my_package.a", ["my_package/a.pyx"]
        ),
    Extension("my_package.b", ["my_package/b.pyx"]
)
]

for e in extensions:
    e.cython_directives = {"embedsignature": True}

setup(
    name = "preprocess",
    ext_modules = cythonize(extensions),
)

setelah menjalankan python setup.py build_ext --inplace tidak ada kesalahan kompilasi. Tetapi jika saya mencoba menjalankan test.py hasilnya ImportError: No module named my_package.b.

Setiap masukan akan dihargai.

BTW jika kita mengubah baris pertama a.pyx dari cimport my_package.b as b menjadi import b itu akan berhasil.


person user2660324    schedule 24.05.2018    source sumber


Jawaban (1)


Agar cimport dari sub-paket berfungsi, direktori paket harus berisi __init__.pxd.

Ini setara dengan __init__.py untuk cimport, bukan import.

Jadikan struktur direktori menjadi seperti ini:

.
├── my_package
│   ├── a.pyx
│   ├── b.pyx
│   ├── b.pxd
│   ├── test.py
│   └── __init__.py
│   └── __init__.pxd
└── setup.py

Kemudian sertakan file pxd sebagai paket data di setup.py agar dapat diinstal:

from setuptools import setup, Extension
from Cython.Build import cythonize

extensions = [
    Extension("my_package.a", ["my_package/a.pyx"]
        ),
    Extension("my_package.b", ["my_package/b.pyx"]
)
]

for e in extensions:
    e.cython_directives = {"embedsignature": True}

package_data = {'my_package': ['*.pxd']}

setup(
    name = "preprocess",
    ext_modules = cythonize(extensions),
    include_package_data=True,
    package_data=package_data,
)

Catatan - import numpy tidak boleh ada di setup.py karena akan membuat paket instalasi tidak berfungsi kecuali numpy telah diinstal.

Masukkan ke dalam requirements.txt untuk menginstalnya bersama dengan paketnya.

person danny    schedule 25.05.2018
comment
Hai Terima kasih atas jawabannya, saya masih memiliki beberapa pertanyaan. 1. Saya mendapatkan Unknown distribution option: 'include_package_data' setelah mencoba setup.py Anda. Saya sudah mencoba menginstal python-distutils-extra (di ubuntu 16.04), tetapi peringatan tidak berbunyi. 2. Saya berasumsi init.pxd adalah file kosong seperti init.py? 3. Apakah anda mempunyai referensi yang dapat saya pelajari? - person user2660324; 25.05.2018
comment
Telah diperbarui - perlu mengimpor dari setuptools dan mungkin juga memperbarui alat pengaturan. __init__.pxd harus kosong. dokumen Cython cukup bagus, meskipun tidak mencakup semuanya. Belajar sambil melakukan berhasil dengan baik. - person danny; 29.05.2018