2012-07-10 81 views
2

我是编程新手,想知道如何让python程序执行并与c程序通信。我正在做一个Python的数学计算,并想知道我是否可以用C语言编写主要的计算,这样计算运行得更快。我一直在阅读关于“从python调用c函数”,“在你的Python代码中直接包含C或C++代码”以及“使用python的c库”。这是一回事吗?我想要一个python程序来执行一个c程序并接收结果。从python程序执行c程序

从python“调用C库函数”是什么意思?它会允许python脚本使用c库还是允许脚本在c编译器内执行代码?

感谢

+0

具体来说,您一直在阅读[本页](http://docs.python.org/extending/extending.html)? – 2012-07-10 19:00:17

+0

可能的重复[如何连接Python和C程序?](http://stackoverflow.com/questions/4743748/how-do-i-connect-a-python-and-ac-program) – senderle 2012-07-10 19:12:06

+0

请参阅尤其是[这个答案](http://stackoverflow.com/a/4743943/577088)涵盖了色域。 – senderle 2012-07-10 19:13:59

回答

0

你想ctypes。它可以让你直接从Python运行C函数,而不需要任何疯狂的扩展。当然,你应该确保你没有过早地优化。 Python的数学函数非常快。

ctypes模块允许您直接从Python代码调用C库函数。这意味着它可以让你将编译的库放到Python可以到达的地方并运行这些已编译的函数。这与从Conrad指出可以用子进程完成的Python调用C程序并不相同。当然,子进程不需要用C编写的程序。它可以运行任何可执行文件。

4

最简单的方法之一是Cython。你可以编写非常接近Python的代码,但是它可以编译成C语言。这使得一些代码(特别是数值计算)快得多。您也可以使用Cython轻松地从Python调用C库函数,尽管ctypes也足够。

但是,如果您确实想要执行特定的C程序,则可以使用Subprocess执行此操作。 N.B.,这比直接调用C库或Cython函数要慢很多。

+0

我用[Multiprocessing](http://docs.python.org/library/multiprocessing.html)使用Subprocess来运行用C编写的数值密集型进程的多个副本,并用Python分析结果。这非常简单。 – StuGrey 2012-07-10 19:13:39

+0

男人,我不是最聪明的程序员。除了http://docs.python.org/library/subprocess.html#module-subprocess还有其他资源可以学习吗? – user1481337 2012-07-10 19:15:53

+2

@ user1481337,实际上'subprocess'文档给出的例子非常好。对于'subprocess',['check_output']的真正基本用法(http://docs.python.org/library/subprocess.html#subprocess。check_output)就足够了。只要将一个命令和任何参数传递给列表,如第一个用法示例所示:'subprocess.check_output([“echo”,“Hello World!”])''。无论命令打印出来什么都将作为字符串返回。 – senderle 2012-07-10 19:28:23

2

还有一些numpy,在处理“数组操作”(有时也称为矢量操作,但我觉得这个术语与SIMD术语混淆)时可以相当快。如果你决定使用cython路由,你可能需要numpy,所以如果这个算法不是太复杂,你可能需要先看看numpy是否足够好。

请注意,您可以在此处选择两种不同的路线。你可以使用subprocess,它基本上对你写的其他程序发出系统调用。这很慢,因为您需要启动新进程并将数据发送到进程中,然后从进程中读回数据。换句话说,每次调用都会多次复制数据。第二条路线是从python调用C函数。由于Cpython(参考和最常见的python实现)是用C语言编写的,所以您可以创建C扩展。它们基本上是遵循某个API的编译库。然后Cpython可以加载这些库并使用里面的函数,传递指向数据的指针。通过这种方式,数据实际上不会被复制 - 您正在使用与您在C中使用的python中相同的内存块。这里的缺点是C API有点复杂。这就是第三方扩展和现有库进来的地方(numpy,cython,ctypes等)。它们都有不同的方式来推动计算int C函数,而不必担心C API。 Numpy删除循环,以便可以快速地添加,减去,乘以数组(其他许多事情)。 Cython将python代码转换为C,然后您可以编译和导入 - 通常为了获得速度,您需要提供其他提示以允许cython优化生成的代码,因为您必须重新指定C函数,因此​​有点脆弱原型,但除此之外,只要您可以将库编译为共享对象,就非常容易...该列表可以继续。

另请注意,如果你不使用numpy,你可能想看看pypy。它声称比Cpython更快地运行Python代码。

1

选项浮现在脑海:

  1. 用Cython:Python中的一种方言,可以自由搭配Python和C数据类型。如果你给主循环所有的C类型进行操作,那么可以为类提供少量的类型注释,并且速度会更快。目前只有很多CPython,但是有人讨论过让它与Pypy合作。
  2. SWIG:一种接口/粘合语言,用于将C库与潜在的大量高级语言(包括CPython)进行匹配。
  3. ctypes:允许您调用个别C函数并访问各个C数据类型。除非在C代码中花费大量时间,否则不会在CPython中燃烧。可能有点脆。也适用于Pypy。
  4. C扩展模块:CPython的漂亮标准 - 这是标准库放在一起的CPython的多少。如果您使用cpyext,一些但不是全部与Pypy一起工作。简而言之,用C语言编写一个带有一堆锅炉板的模块,但它可以从CPython调用。
  5. CFFI:来自Pypy项目的新的外部函数接口。他们现在正在与CPython合作,并打算不久之后与Pypy合作。它就像ctypes,但不那么脆弱 - 缺点是运行时需要一个C编译器,而且它非常年轻的代码。
  6. Pypy:这实际上并不是一种调用C本身的方式,但是对于很多纯Python代码,它的速度几乎与C一样快。如果你没有很多你需要的C扩展模块,那么Pypy可能是一个很好的选择。
  7. subprocess:一种非常便携的与另一个进程交互的方式,不一定是相同的语言。可以与子进程中的任何语言一起使用。除非你花费很少的时间来回传递数据,否则不会快速发展。几乎所有交换的数据都必须被序列化为ASCII或其他东西,但它非常便携,简单且松耦合,值得思考。
  8. 你也许能够只优化你的Python:http://wiki.python.org/moin/PythonSpeed/PerformanceTips

不要急于在C编码 - 它更昂贵的编程时间方面,而且容易隐蔽,很难发现漏洞。首先在Pure Python中运行你的代码,以使程序以任何速度产生正确的结果,然后如果你发现程序太慢,则对程序进行轮廓分析,以决定哪个部分需要以某种方式重做以上所列。通常你只需要你的程序的0-2%用纯Python以外的东西来完成 - 也可以尽可能多地节省程序员的时间。