2009-06-18 12 views
0

私はPythonユーティリティ関数をいくつか追加したいC拡張モジュールを持っています。これを行うための推奨方法はありますか?例えばモジュール内で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.soや_mymod.pydからインポートされたCで書かれた_mymodモジュールにあるものがインポートされます。たとえば、Pythonディストリビューションの.../Lib/csv.pyを見てください。

+0

csv.pyは本当に役立つ例です –

5

ネイティブ拡張にアンダースコアを付加します。 次に、Pythonで、そのネイティブ拡張をインポートし、他の非ネイティブルーチンをその上に追加するラッパーモジュールを作成します。

1

既存の回答には、最も頻繁に使用される方法が記載されています。コンパイル済みのC拡張が利用できないプラットフォーム(JythonとIronPythonを含む)でpure Python(または他言語)の実装を可能にするという利点があります。

ただし、Cで書かれたものよりもPythonで書かれたほんの少しのエクストラを提供するために、モジュールをC層とPython層に分割する価値はないかもしれません。たとえば、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); 

あなたのモジュールに 『固執』し、それらのいくつかの余分な機能をしたい場合は(必要はありません。この例では場合)、モジュールオブジェクトをPy_InitModule3(または他の方法であれ)で作成し、PyModule_GetDictという名前の一時的な辞書ではなく、 PyRun_String。もちろん、PyRun_Stringdefclassのステートメントよりも洗練されたアプローチがありますが、簡単なケースでは、この単純なアプローチで十分です。

+0

ありがとう:私はこれがどのようにして一般的な方法で行われるのか興味がありました。 –

関連する問題