Frage

Ich habe ein C-Erweiterungsmodul, an denen Ich mag würde einige Python Utility-Funktionen hinzuzufügen. Gibt es eine empfohlene Weg, dies zu tun?

Zum Beispiel:

import my_module

my_module.super_fast_written_in_C()
my_module.written_in_Python__easy_to_maintain()

Ich bin in erster Linie interessiert in Python 2.x.

War es hilfreich?

Lösung

Der üblicher Weg, dies zu tun ist: mymod.py enthält die Utility-Funktionen in Python geschrieben und importiert die Leckereien in dem _mymod-Modul, das in C geschrieben ist und von _mymod.so oder _mymod.pyd importiert. Zum Beispiel, schaut ... / Lib / csv.py in Ihrer Python-Distribution.

Andere Tipps

Präfix Ihrer native Erweiterung mit einem Unterstrich. Dann in Python, erstellen Sie ein Wrapper-Modul, das die native Erweiterung importiert und fügt einige andere nicht-native Routinen obendrein.

Die bestehenden Antworten beschreiben das Verfahren am häufigsten verwendet. Das Potenzial Vorteil, dass pure-Python (oder andere-Sprache) Implementierungen auf Plattformen, in denen die kompilierte C-Erweiterung nicht verfügbar ist (einschließlich Jython und Ironpython)

In einigen Fällen kann es jedoch nicht wert sein, das Modul in eine C-Schicht spalten und eine Python-Schicht nur ein paar Extras zu schaffen, die als beispielsweise in C in Python sinnvoller geschrieben werden, gmpy (Zeilen 7113 ff zu diesem Zeitpunkt), um zu ermöglichen Beizen von Instanzen von gmpy des Typs verwendet:

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);

Wenn Sie diese paar zusätzlichen Funktionen „bleiben, um“ in Ihrem Modul (nicht notwendig, in diesem Beispielfall) wollen, können Sie natürlich würden Ihr Modul-Objekt verwenden, wie durch Py_InitModule3 gebaut (oder was auch immer andere Verfahren) und seine PyModule_GetDict statt ein transienter Wörterbuch als Namensraum, in dem PyRun_String. Und natürlich gibt es anspruchsvollere Ansätze als die PyRun_String und def Aussagen class Sie brauchen, aber für einfache genug Fälle, dieser einfache Ansatz in der Tat ausreichend sein kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top