В существующих ответах описывается наиболее часто используемый метод: у него есть потенциальное преимущество использования реализаций pure-Python (или другого языка) на платформах, в которых скомпилированное расширение C недоступно (включая Jython и IronPython).
В некоторых случаях, однако, может не стоить разделить модуль на С-слой и слой Python, чтобы предоставить несколько дополнительных функций, которые более разумно записаны на Python, чем в C. Например, gmpy (строки 7113 и далее в это время), с тем чтобы травление экземпляров типа gmpy
«s, использует:
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_String
, необходимые вам и class
заявлениями, но для простых случаев этого простого подхода на самом деле может быть достаточно.
csv.py - действительно полезный пример –