2009-06-18 14 views
0

我有一個C擴展模塊,我想添加一些Python實用函數。有推薦的方法嗎?在模塊中結合C和Python函數

例如:

import my_module 

my_module.super_fast_written_in_C() 
my_module.written_in_Python__easy_to_maintain() 

我在Python 2.x的主要興趣

回答

7

執行此操作的常用方法是:mymod.py包含用Python編寫的實用程序函數,並在_mymod模塊中導入好的東西,該模塊用C語言編寫,並從_mymod.so或_mymod.pyd導入。例如,查看Python發行版中的.../Lib/csv.py。

+0

csv.py是一個非常有用的示例 – 2009-06-19 08:21:19

5

使用下劃線前綴固有擴展名。 然後,在Python中,創建一個包裝模塊,用於導入本機擴展並在其上添加一些其他非本機例程。

1

現有的答案描述了最常用的方法:它具有在編譯的C擴展名不可用的平臺(包括Jython和IronPython)上允許純Python(或其他語言)實現的潛在優勢。

然而,在少數情況下,將模塊分割爲C層和Python層可能並不值得,只是爲了提供一些Python中比C更明智的額外元素。例如,gmpy(行此時7113個FF),爲了使gmpy的類型的實例酸洗,用途:

copy_reg_module = PyImport_ImportModule("copy_reg"); 
if (copy_reg_module) { 
    char* enable_pickle = 
     "def mpz_reducer(an_mpz): return (gmpy.mpz, (an_mpz.binary(), 256))\n" 
     "def mpq_reducer(an_mpq): return (gmpy.mpq, (an_mpq.binary(), 256))\n" 
     "def mpf_reducer(an_mpf): return (gmpy.mpf, (an_mpf.binary(), 0, 256))\n" 
     "copy_reg.pickle(type(gmpy.mpz(0)), mpz_reducer)\n" 
     "copy_reg.pickle(type(gmpy.mpq(0)), mpq_reducer)\n" 
     "copy_reg.pickle(type(gmpy.mpf(0)), mpf_reducer)\n" 
    ; 
    PyObject* namespace = PyDict_New(); 
    PyObject* result = NULL; 
    if (options.debug) 
     fprintf(stderr, "gmpy_module imported copy_reg OK\n"); 
    PyDict_SetItemString(namespace, "copy_reg", copy_reg_module); 
    PyDict_SetItemString(namespace, "gmpy", gmpy_module); 
    PyDict_SetItemString(namespace, "type", (PyObject*)&PyType_Type); 
    result = PyRun_String(enable_pickle, Py_file_input, 
          namespace, namespace); 

如果你想那幾個額外的功能,你的模塊中,以‘堅持圍繞’(沒有必要在這個例子中case),當然你會使用Py_InitModule3(或任何其他方法)和它的PyModule_GetDict構建的模塊對象,而不是臨時字典作爲名稱空間PyRun_String。當然,還有更復雜的方法比PyRun_Stringdefclass陳述你需要,但是,對於簡單的情況下,這種簡單的方法可能實際上是足夠的。

+0

謝謝:我有興趣瞭解如何做到這一點,以及更常見的方式。 – 2009-06-19 08:19:21