ข้อผิดพลาดในการนำเข้า Cython ในแพ็คเกจเดียวกัน

ฉันเคยเห็นคำถามนี้ และดูเหมือนว่าคำตอบจะไม่ได้ผล ต่อไปนี้เป็นโครงสร้างไดเร็กทอรีของฉัน

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

ไฟล์ a.pyx

cimport my_package.b  as b

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

ไฟล์ b.pyx

cdef class b:

    def __init__(self):
        pass

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

ไฟล์ b.pxd

cdef class b:
    cpdef run(self)

test.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),
)

หลังจากรัน python setup.py build_ext --inplace แล้วไม่มีข้อผิดพลาดในการคอมไพล์ แต่ถ้าฉันพยายามเรียกใช้ test.py มันจะให้ ImportError: No module named my_package.b

ข้อมูลใด ๆ จะได้รับการชื่นชม

BTW ถ้าเราเปลี่ยนบรรทัดแรกของ a.pyx จาก cimport my_package.b as b เป็น import b มันจะใช้ได้


person user2660324    schedule 24.05.2018    source แหล่งที่มา


คำตอบ (1)


เพื่อให้ cimport ของแพ็คเกจย่อยทำงานได้ ไดเร็กทอรีแพ็คเกจจะต้องมี __init__.pxd

มันเทียบเท่ากับ __init__.py สำหรับ cimport แทนที่จะเป็น import

ทำให้โครงสร้างไดเร็กทอรีเป็นดังนี้:

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

จากนั้นรวมไฟล์ pxd เป็นข้อมูลแพ็คเกจใน setup.py เพื่อให้ทำการติดตั้ง:

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,
)

หมายเหตุ - import numpy ไม่ควรอยู่ใน setup.py เนื่องจากจะทำให้การติดตั้งแพ็คเกจไม่ทำงาน เว้นแต่จะมีการติดตั้ง numpy แล้ว

ใส่ไว้ใน requirements.txt เพื่อติดตั้งพร้อมกับแพ็คเกจ

person danny    schedule 25.05.2018
comment
สวัสดี ขอบคุณสำหรับคำตอบ ฉันยังมีคำถามอยู่บ้าง 1. ฉันได้รับ Unknown distribution option: 'include_package_data' หลังจากลองใช้ setup.py ของคุณ ฉันได้ลองติดตั้ง python-distutils-extra (ใน Ubuntu 16.04) แล้ว แต่คำเตือนไม่ดับลง 2. ฉันถือว่า init.pxd เป็นไฟล์เปล่าเหมือนกับ init.py? 3. คุณมีข้อมูลอ้างอิงใดบ้างที่ฉันสามารถเรียนรู้ได้? - person user2660324; 25.05.2018
comment
อัปเดตแล้ว - จำเป็นต้องนำเข้าจาก setuptools และอาจอัปเดตเครื่องมือการตั้งค่าด้วย __init__.pxd ควรเว้นว่างไว้ เอกสาร Cython ค่อนข้างดี แม้ว่าจะไม่ครอบคลุมทุกอย่างก็ตาม การเรียนรู้จากการทำงานให้ดี - person danny; 29.05.2018