擅长:python、mysql、java
<p>警告:Cython核心开发者的意见。</p>
<p>我几乎总是推荐Cython胜过ctypes。原因是它有一个更平滑的升级路径。如果使用ctypes,很多事情一开始都会很简单,用普通的Python编写FFI代码当然很酷,不需要编译、构建依赖项等等。然而,在某个时刻,您几乎肯定会发现,您必须经常调用C库,无论是在循环中还是在一系列较长的相互依赖的调用中,您都希望加快调用速度。在这一点上,您将注意到不能对ctypes执行此操作。或者,当您需要回调函数并且发现Python回调代码成为瓶颈时,您希望加快它的速度,并/或将它向下移动到C中。同样,不能对ctypes执行此操作。因此,您必须在此时切换语言并开始重写部分代码,可能会将Python/ctypes代码反向工程为纯C,从而破坏了首先使用纯Python编写代码的全部好处。</p>
<p>使用Cython,OTOH,您可以完全自由地使包装和调用代码尽可能薄或厚。您可以从普通Python代码向C代码的简单调用开始,Cython将它们转换为本地C调用,而不需要任何额外的调用开销,并且Python参数的转换开销极低。当您注意到在某个点上需要更高的性能时,如果您对C库进行了太多代价高昂的调用,您可以开始用静态类型注释您周围的Python代码,并让Cython直接将其优化为C。或者,可以开始用Cython重写部分C代码,以避免调用,并在算法上专门化和收紧循环。如果需要快速回调,只需编写一个带有适当签名的函数,并将其直接传递到C回调注册表。同样,没有开销,而且它提供了简单的C调用性能。而且在Cython的代码中,你不能很快地得到代码的可能性要小得多,你仍然可以考虑重写C(或C++或FORTRAN)中真正重要的部分,并从Cython代码自然地和本地地调用它。但是,这确实是最后的选择,而不是唯一的选择。</p>
<p>所以,ctypes很适合做一些简单的事情,并且能够快速地运行一些东西。然而,一旦事情开始发展,你很可能会发现你最好从一开始就使用Cython。</p>