2012-07-10 82 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以外的東西來完成 - 也可以儘可能多地節省程序員的時間。