2015-05-10 23 views
7

setup.py này:Collapse nhiều submodules một phần mở rộng Cython

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

extensions = (
    Extension('myext', ['myext/__init__.py', 
         'myext/algorithms/__init__.py', 
         'myext/algorithms/dumb.py', 
         'myext/algorithms/combine.py']) 
) 
setup(
    name='myext', 
    ext_modules=cythonize(extensions) 
) 

Không có tác dụng dự định. Tôi muốn nó để sản xuất một đơn myext.so, mà nó; nhưng khi tôi gọi nó qua

python -m myext.so 

tôi nhận được:

ValueError: Attempted relative import in non-package 

do thực tế rằng myext nỗ lực để tham khảo .algorithms.

Bất kỳ ý tưởng nào về cách làm việc này?

+0

Hướng dẫn này có giúp ích cho bạn không? https://github.com/cython/cython/wiki/PackageHierarchy –

+0

Tôi đã thực sự đọc và theo dõi điều đó; vấn đề là họ không có đầu ra nhị phân đơn. Chúng tạo ra một nhị phân cho mỗi tệp Python. – Reinderien

Trả lời

4

Trước hết, tôi nên lưu ý rằng đó là impossible để biên dịch một tệp .so đơn lẻ với các gói con bằng cách sử dụng Cython. Vì vậy, nếu bạn muốn các gói con, bạn sẽ phải tạo nhiều tệp .so, vì mỗi tệp .so chỉ có thể đại diện cho một mô-đun.

Thứ hai, có vẻ như bạn không thể biên dịch nhiều tệp Cython/Python (tôi đang sử dụng ngôn ngữ Cython cụ thể) và liên kết chúng thành một mô-đun duy nhất.

Tôi đã cố gắng biên dịch nhiều tệp Cython thành một .so mỗi cách, cả hai với distutils và bằng cách biên dịch thủ công và luôn không nhập được khi chạy. Có vẻ như việc liên kết tệp Cython được biên dịch với các thư viện khác hoặc thậm chí là các tệp C khác, nhưng có điều gì đó sai khi liên kết với nhau hai tệp Cython được biên dịch và kết quả không phải là một phần mở rộng Python thích hợp.

Giải pháp duy nhất tôi có thể thấy là biên dịch mọi thứ dưới dạng tệp Cython duy nhất. Trong trường hợp của tôi, tôi đã chỉnh sửa setup.py của tôi để tạo ra một tập tin duy nhất .pyx mà lần lượt include s mỗi .pyx tập tin trong thư mục nguồn của tôi:

includesContents = "" 
for f in os.listdir("src-dir"): 
    if f.endswith(".pyx"): 
     includesContents += "include \"" + f + "\"\n" 

includesFile = open("src/extension-name.pyx", "w") 
includesFile.write(includesContents) 
includesFile.close() 

Sau đó, tôi chỉ cần biên dịch extension-name.pyx. Tất nhiên điều này phá vỡ biên dịch gia tăng và song song, và bạn có thể kết thúc với xung đột đặt tên thêm kể từ khi tất cả mọi thứ được dán vào cùng một tập tin. Về mặt tươi sáng, bạn không phải viết bất kỳ tệp .pyd nào.

Tôi chắc chắn sẽ không gọi đây là phương pháp xây dựng thích hợp hơn, nhưng nếu mọi thứ hoàn toàn nằm trong một mô-đun mở rộng, đây là cách duy nhất tôi có thể thấy để thực hiện.

Các vấn đề liên quan