سؤال

ولدي حدة الإرشاد C، والتي أود أن أضيف بعض الوظائف ذات المنفعة بيثون. هل هناك طريقة الموصى بها من القيام بذلك؟

وعلى سبيل المثال:

import my_module

my_module.super_fast_written_in_C()
my_module.written_in_Python__easy_to_maintain()

وأنا مهتم في المقام الأول في 2.x بيثون.

هل كانت مفيدة؟

المحلول

والطريقة المعتادة للقيام بذلك هي: mymod.py يحتوي على الوظائف ذات المنفعة مكتوبة في بيثون، وتستورد الأشياء الجيدة في وحدة _mymod الذي هو مكتوب في C ويتم استيرادها من _mymod.so أو _mymod.pyd. على سبيل المثال، أن ننظر في ... / ليب / csv.py في توزيع بيثون الخاص بك.

نصائح أخرى

والبادئة الإضافة الأصلي الخاص بك مع تسطير. ثم، في بيثون، إنشاء وحدة نمطية المجمع أن تستورد أن الإضافة الأصلي، ويضيف بعض إجراءات أخرى غير الأم على أعلى من ذلك.

والأجوبة الموجودة تصف طريقة الأكثر استخداما: أنه لديه ميزة محتملة السماح للتطبيقات على منصات فيه تمديد C جمعتها غير متوفر (بما في ذلك جيثون وو IronPython) نقية بيثون (أو غيرها من اللغات)

في حالات قليلة، ومع ذلك، فإنه قد لا يكون من المفيد تقسيم وحدة في طبقة C وطبقة بيثون فقط لتقديم إضافات قليلة التي تتم كتابتها أكثر معقولة في بيثون مما كانت عليه في C. على سبيل المثال، <أ href = ل "http://code.google.com/p/gmpy/source/browse/trunk/src/gmpy.c" يختلط = "نوفولو noreferrer"> gmpy (خطوط 7113 وما يليها في هذا الوقت)، من أجل لتمكين تخليل من الحالات من النوع 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_String البيانات def وclass التي تحتاج إليها، ولكن، لحالات بسيطة بما فيه الكفاية، وهذا النهج بسيط قد يكون كافيا في الواقع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top