我想从Python应用程序中调用C库.我不想包装整个API,只包含与我的案例相关的函数和数据类型.在我看来,我有三个选择:
我不确定2)或3)是否是更好的选择.3)的优点是它ctypes
是标准库的一部分,结果代码将是纯Python - 尽管我不确定这个优势实际上有多大.
两种选择都有更多优点/缺点吗?你推荐哪种方法?
编辑:感谢您的所有答案,他们为希望做类似事情的人提供了一个很好的资源.当然,这个决定仍然是针对单个案例做出的 - 没有人"这是正确的事情"的答案.对于我自己的情况,我可能会选择ctypes,但我也期待在其他项目中尝试Cython.
由于没有一个真正的答案,接受一个有点武断; 我选择了FogleBird的答案,因为它提供了对ctypes的一些很好的洞察力,它目前也是最高投票的答案.但是,我建议阅读所有答案以获得良好的概述.
再次感谢.
我想制作一个包含一些Cython代码的Python包.我已经很好地运行了Cython代码.但是,现在我想知道如何最好地打包它.
对于大多数只想安装软件包的人来说,我想要包含.c
Cython创建的文件,并安排setup.py
编译它以生成模块.然后用户不需要安装Cython来安装软件包.
但对于谁可能要修改包的人,我也想提供用Cython .pyx
文件,并以某种方式也允许setup.py
使用用Cython编译它们(因此这些用户将需要安装用Cython).
我应该如何构建包中的文件以满足这两种情况?
在用Cython文档提供了一些指导.但它没有说明如何制作一个单独setup.py
处理有/无Cython情况.
我试图加快答案在这里使用用Cython.我尝试编译代码(在执行此处cygwinccompiler.py
解释的hack 之后),但是出错了.任何人都可以告诉我,如果这是我的代码的问题,或Cython的一些深奥的微妙?fatal error: numpy/arrayobject.h: No such file or directory...compilation terminated
以下是我的代码.提前致谢:
import numpy as np
import scipy as sp
cimport numpy as np
cimport cython
cdef inline np.ndarray[np.int, ndim=1] fbincount(np.ndarray[np.int_t, ndim=1] x):
cdef int m = np.amax(x)+1
cdef int n = x.size
cdef unsigned int i
cdef np.ndarray[np.int_t, ndim=1] c = np.zeros(m, dtype=np.int)
for i in xrange(n):
c[<unsigned int>x[i]] += 1
return c
cdef packed struct Point:
np.float64_t f0, f1
@cython.boundscheck(False)
def sparsemaker(np.ndarray[np.float_t, ndim=2] …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用mingw(64位)在win 7 64位中使用cython编译python扩展.
我正在使用Python 2.6(Active Python 2.6.6)和足够的distutils.cfg文件(将mingw设置为编译器)
执行时
> C:\Python26\programas\Cython>python setup.py build_ext --inplace
Run Code Online (Sandbox Code Playgroud)
我得到一个错误,说gcc没有-mno-cygwin选项:
> C:\Python26\programas\Cython>python setup.py build_ext --inplace
running build_ext
skipping 'hello2.c' Cython extension (up-to-date)
building 'hello2' extension
C:\mingw\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\Python26\include -IC:\Python26\PC -c hello2.c -o build\temp.win-amd64-2.6\Release\hello2.o
gcc: error: unrecognized command line option '-mno-cygwin'
error: command 'gcc' failed with exit status 1
Run Code Online (Sandbox Code Playgroud)
gcc是:
C:\>gcc --version
gcc (GCC) 4.7.0 20110430 (experimental)
Copyright (C) 2011 Free Software Foundation, Inc.
Run Code Online (Sandbox Code Playgroud)
我该怎么办呢?
我有一个Python2.6程序,可以使用Cython加载编译为.so文件的Python模块.我用Cython将.py模块编译成.so文件,一切正常.
这是我在Cython中使用的setup.py文件:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("ldap", ["ldap.pyx"]),
Extension("checker", ["checker.pyx"]),
Extension("finder", ["finder.pyx"]),
Extension("utils", ["utils.pyx"]),
]
setup(
name = 'bchecker',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
Run Code Online (Sandbox Code Playgroud)
所以我知道我可以使用Cython编译Python模块(我猜Cython从我的Python文件创建'C'文件然后编译它们),但是我可以将我的主Python程序编译成可以在Linux平台上执行的程序吗?如果是这样,将欣赏Cython命令行示例.谢谢.
我正在编写一个包含Cython扩展和使用LAPACK
(和BLAS
)的Python模块.我打开使用两种clapack
或lapacke
,或某种f2c
或f2py
解决方案,如果必要的.最重要的是,我能够调用lapack
并blas
从用Cython在紧密循环不Python的调用开销例程.
我在这里找到了一个例子.但是,该示例取决于SAGE.我希望我的模块可以在不安装SAGE的情况下进行安装,因为我的用户不太可能想要或不需要SAGE.我的用户很可能安装了numpy,scipy,pandas和scikit的软件包,所以这些都是合理的依赖.使用的接口的最佳组合是什么,以及最小的setup.py文件看起来可以获取必要的信息(来自numpy,scipy等)以进行编译?
编辑: 这是我最终做的.它适用于我的macbook,但我不知道它是多么便携.当然有更好的方法.
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy
from Cython.Build import cythonize
from numpy.distutils.system_info import get_info
# TODO: This cannot be the right way
blas_include = get_info('blas_opt')['extra_compile_args'][1][2:]
includes = [blas_include,numpy.get_include()]
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = cythonize([Extension("cylapack", ["cylapack.pyx"],
include_dirs = includes,
libraries=['blas','lapack'])
])
)
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为在我的macbook上,clapack.h
头文件与...相同cblas.h
.然后我可以在我的pyx文件中执行此操作:
ctypedef np.int32_t …
Run Code Online (Sandbox Code Playgroud) 有关类型化内存视图的Cython文档列出了三种分配给类型化内存视图的方法:
np.ndarray
和cython.view.array
.假设我没有从外部传入我的cython函数的数据,而是想分配内存并将其作为a返回np.ndarray
,我选择了哪些选项?还假设该缓冲区的大小不是编译时常量,即我不能在堆栈上分配,但需要malloc
选项1.
因此,3个选项可以解释如下:
from libc.stdlib cimport malloc, free
cimport numpy as np
from cython cimport view
np.import_array()
def memview_malloc(int N):
cdef int * m = <int *>malloc(N * sizeof(int))
cdef int[::1] b = <int[:N]>m
free(<void *>m)
def memview_ndarray(int N):
cdef int[::1] b = np.empty(N, dtype=np.int32)
def memview_cyarray(int N):
cdef int[::1] b = view.array(shape=(N,), itemsize=sizeof(int), format="i")
Run Code Online (Sandbox Code Playgroud)
让我感到惊讶的是,在所有三种情况下,Cython为内存分配生成了大量代码,特别是调用__Pyx_PyObject_to_MemoryviewSlice_dc_int
.这表明(我可能在这里错了,我对Cython内部工作的洞察力非常有限),它首先创建一个Python对象,然后将其"转换"到内存视图中,这似乎是不必要的开销.
一个简单的基准测试并未揭示三种方法之间存在很大差异,其中2是最薄弱的方法.
推荐三种方法中的哪一种?或者有更好的选择吗? …
我正在构建一个 django-react 站点,突然我的 docker-compose 不再构建,尽管需求或图像版本发生了任何更改。
\n我的requirements.txt 如下所示:
\nDjango>=3.2.4,<4.0\ndjangorestframework>=3.12.4,<3.14.0\ndjangorestframework-simplejwt>=4.8.0,<5.3.0\npsycopg2>=2.8.6,<2.9\ndrf-spectacular>=0.15.1,<0.30\ndjango-allauth>0.5,<1.0\ndj-rest-auth>=3.0,<4.0\n
Run Code Online (Sandbox Code Playgroud)\n错误输出:
\n => [backend internal] load .dockerignore 0.0s \n => => transferring context: 234B 0.0s \n => [backend internal] load build definition from Dockerfile 0.0s \n => => transferring dockerfile: 933B 0.0s \n => [backend internal] load metadata for docker.io/library/python:3.9-alpine3.13 0.5s \n => [backend 1/6] FROM docker.io/library/python:3.9-alpine3.13@sha256:a7cbd1e7784a35a098cedbc8681b790d35ff6030a5e13f043185e2465003a040 0.0s \n => [backend internal] load build context 0.0s \n => => transferring context: 2.53kB 0.0s \n => CACHED [backend 2/6] WORKDIR …
Run Code Online (Sandbox Code Playgroud) 我发现了我的python代码中的瓶颈,与psycho等一起玩.然后决定为性能编写ac/c ++扩展.
在swig的帮助下,你几乎不需要关心论点等.一切正常.
现在我的问题是:swig创建了一个非常大的py文件,它在调用实际的.pyd或.so代码之前执行了很多'checkings'和'PySwigObject'.
如果你手写这个文件或者让swig这样做,你们中是否有人有任何经验可以获得更多的性能.
我想用Cython包装一个包含C++和OpenMP代码的测试项目,并通过setup.py
文件使用distutils构建它.我的文件内容如下所示:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext
modules = [Extension("Interface",
["Interface.pyx", "Parallel.cpp"],
language = "c++",
extra_compile_args=["-fopenmp"],
extra_link_args=["-fopenmp"])]
for e in modules:
e.cython_directives = {"embedsignature" : True}
setup(name="Interface",
cmdclass={"build_ext": build_ext},
ext_modules=modules)
Run Code Online (Sandbox Code Playgroud)
该-fopenmp
标志与gcc一起用于编译和链接OpenMP.但是,如果我只是调用
cls ~/workspace/CythonOpenMP/src $ python3 setup.py build
Run Code Online (Sandbox Code Playgroud)
这个标志无法识别,因为编译器是clang:
running build
running build_ext
skipping 'Interface.cpp' Cython extension (up-to-date)
building 'Interface' extension
cc -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -c Interface.cpp -o build/temp.macosx-10.8-x86_64-3.3/Interface.o …
Run Code Online (Sandbox Code Playgroud)