Rất nhiều người sử dụng Cython để biên dịch mã Python của họ trong C để đạt được hiệu suất. Nó rất dễ làm và có thể là thứ mà bạn muốn tận dụng.
Hãy chắc chắn rằng bạn PIP cài đặt Cython trước.
Quá trình tổng thể đi như thế này.
- Mang các phần mã của bạn mà bạn muốn chuyển đổi thành C thành một tệp riêng biệt
- Cung cấp thông tin loại và cho Cython biết những gì bạn muốn sử dụng trong Python và những gì bạn tặng.
- biên dịch tệp riêng biệt bằng tệp setup.py
Ví dụ này, hãy để nói rằng chúng tôi muốn biên dịch chức năng này thành C
def AddToTen[]:
x = 0for i in range[1,11]:
x+=i
return x
Điều đầu tiên chúng ta cần làm là di chuyển điều này từ tệp .py vào tệp .pyx, đó là những gì Cython sử dụng. Bây giờ chúng tôi sẽ cung cấp thông tin loại cho các biến của chúng tôi
Bạn muốn đọc câu chuyện này sau? Lưu nó trong tạp chí.
Ở Cython, có ba tuyên bố DEF
- CDEF: Khai báo một cái gì đó sẽ được sử dụng trong C [như các biến bên trong hàm của chúng tôi]
- PDEF: Tuyên bố một cái gì đó sẽ chỉ được sử dụng trong Python
- CPDEF: Khai báo một cái gì đó sẽ được sử dụng trong cả hai
cpdef int AddToTen[]:
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Vì tôi sẽ không gọi các biến bên trong chức năng của chúng tôi trong Python, tôi đã sử dụng CDEF, nhưng đối với chính chức năng, tôi đã sử dụng CPDEF
Ngoài ra, lưu ý rằng chúng tôi đã nhập I trong vòng lặp và hàm vì nó trả về int.
Bây giờ chúng ta phải biên dịch .pyx của chúng tôi. Trong một tệp riêng biệt [của tôi được đặt tên là setup.py], hãy viết mã sau.
from distutils.core import setup
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
Cuối cùng, trong thiết bị đầu cuối [đảm bảo bạn đang ở trong cùng một thư mục], hãy chạy dòng
python setup.py build_ext --inplace
Điều này nên đã biên dịch pyx của bạn và bạn sẽ thấy một tệp cùng tên với phần mở rộng .c thay vì pyx
Bây giờ bạn có thể nhập các chức năng C của mình vào các tệp Python cục bộ, cho rằng bạn đã sử dụng CPDEF, chỉ bằng cách nhập tên của tệp của bạn. IDE có xu hướng cho tôi lỗi nhập mặc dù họ nhập khẩu tốt. Bạn cũng có thể nhập các thư viện Python vào tệp PYX, nhưng theo kinh nghiệm của tôi, nó thực hiện giống như trong Python.
Khác xa với một chuyên gia C nhưng đối với tôi sử dụng Ubuntu, các tác phẩm sau:
main.c:
#include "foo_api.h"
#include
int main[int argc, char *argv[]] {
Py_Initialize[];
initfoo[];
import_foo[];
double arr[5] = {1,2,3,4,5};
int i = 0;
foo[arr];
for[i = 0; i < 5; i++]
{
printf["%f\n", arr[i]];
}
Py_Finalize[];
return 0;
}
foo.pyx:
cdef public api foo[double* x]:
x[0] = 0.0
Từ cùng một thư mục:
$ cython foo.pyx
Then:
$ cc -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 -o foo *.c -lpython2.7
Sau đó, chỉ cần chạy.
$ ./foo
0.000000
2.000000
3.000000
4.000000
5.000000
Tôi đã sử dụng
from distutils.core import setup2 để lấy cờ:
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
$ pkg-config --cflags python
-I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7
Không gọi py_initialize [khởi tạo trình thông dịch python. Trong một ứng dụng nhúng python, điều này nên được gọi trước khi sử dụng bất kỳ chức năng API Python/C nào khác;], Bạn sẽ nhận được:
cpdef int AddToTen[]:0
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Không có
from distutils.core import setup3 hoặc
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
from distutils.core import setup4 bạn nhận được:
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
cpdef int AddToTen[]:1
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Nếu bạn không gọi py_finalize:
from distutils.core import setup5 A NO-OP khi được gọi lần thứ hai [mà không gọi py_finalize [] trước tiên].
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
Để lấy ví dụ DeLorean từ các tài liệu để chạy:
main.py:
cpdef int AddToTen[]:2
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
delorean.pyx:
cpdef int AddToTen[]:3
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Quy trình này là như nhau, thay đổi duy nhất là tôi phải sử dụng
from distutils.core import setup6 với cấu trúc xe hoặc cách khác trong chính hoặc sử dụng tôi đã sử dụng
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
from distutils.core import setup7 trong chính:
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
cpdef int AddToTen[]:4
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Bạn cũng có thể làm cho nó hoạt động mà không cần sử dụng
from distutils.core import setup5, v.v.
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
Trong
from distutils.core import setup9, bạn chỉ cần công khai chức năng:
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
cpdef int AddToTen[]:5
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Tôi đã thêm
python setup.py build_ext --inplace
0 vừa nhập python setup.py build_ext --inplace
1in main.c và xóa python setup.py build_ext --inplace
2, v.v ... Chỉ cần nhập python setup.py build_ext --inplace
3 sẽ không hoạt động cho tôi nhưng đó có thể không phải là trường hợp của mọi người.cpdef int AddToTen[]:6
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Biên dịch là như nhau:
cpdef int AddToTen[]:7
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Nếu bạn đang sử dụng phiên bản API thì chỉ cần bao gồm tiêu đề API hoặc ngược lại theo tài liệu, tuy nhiên, lưu ý rằng bạn nên bao gồm tên modulename.h hoặc modulename_api.h trong một tệp C đã cho, không phải cả hai định nghĩa.
Để làm tương tự với ví dụ DeLorean, tôi đã phải sử dụng
python setup.py build_ext --inplace
4 để in các chuỗi để tránh lỗi phân đoạn:cpdef int AddToTen[]:8
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
main:
cpdef int AddToTen[]:9
cdef int x = 0
cdef int ifor i in range[1,11]:
x+=i
return x
Có thể có ý nghĩa hơn khi trả về các giá trị:
from distutils.core import setup0
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]
main:
from distutils.core import setup1
from Cython.Build import cythonizesetup[ext_modules = cythonize['The_Name_Of_Your_Pyx_Here.pyx']]