Вызов Python из C | Комплект 2

Опубликовано: 12 Апреля, 2022

Предпосылка: Вызов Python из C | Комплект 1

Чтобы использовать эту функцию, необходимо передать ссылку на существующий вызываемый Python. Для этого есть много способов, например просто написать код на C для извлечения символа из существующего модуля или передать вызываемый объект в модуль расширения.

Code #1 : Simple embedding example

int main()
{
    PyObject * pow_func;
    double x;
    Py_Initialize();
      
    // Get a reference to the math.pow function
    pow_func = import_name("math", "pow");
      
    // Call it using our call_func() code 
    for (x = 0.0; x < 10.0; x += 0.1)
    {
        printf("% 0.2f % 0.2f ", x, call_func(pow_func, x, 2.0));
    }
          
    Py_DECREF(pow_func);
    Py_Finalize();
    return 0;
}


Чтобы построить этот последний пример, C необходимо скомпилировать и связать с интерпретатором Python. В приведенном ниже фрагменте показано, как это сделать (это может потребовать некоторых действий на вашем компьютере):

Код №2:

all::
cc -g embed.c -I/usr/local/include/python3.3m
-L /usr/local/lib/python3.3/config-3.3m -lpython3.3m

Компиляция и запуск полученного исполняемого файла дает следующий результат:

0,00 0,00
0,10 0,01
0,20 0,04
0,30 0,09
0,40 0,16
...

 
There is another example given by the code below that shows an extension function that receives a callable and some arguments and passes them to call_func() for the purposes of testing.

Code #3 :

/* Extension function for testing the C-Python callback */
  
PyObject * py_call_func(PyObject * self, PyObject * args)
{
    PyObject * func;
  
    double x, y, result;
    if (! PyArg_ParseTuple(args, "Odd", &func, &x, &y))
    {
        return NULL;
    }
    result = call_func(func, x, y);
    return Py_BuildValue("d", result);
}

 
Code #4 : Testing the extension function

import work
  
def add(x, y):
    return x + y
  
work.call_func(add, 3, 4)

Выход :

7.0

 
It is critical that first we need to have a Python object representing the callable that is to be invoked. This could be a function, class, method, built-in method, or anything that implements the __call__() operation. To verify whether it is a callable function use PyCallable_Check().

Code #5 : Checking PyCallable_Check() function

double call_func(PyObject *func, double x, double y)
{
    ...
    // Verify that func is a proper callable
    if (!PyCallable_Check(func))
    {
        fprintf(stderr, "call_func: expected a callable ");
        goto fail;
    }
    ...

 
Simply use PyObject_Call() to call a function, supplying it with the callable object, a tuple of arguments, and an optional dictionary of keyword arguments.

Py_BuildValue() can be used to build the argument tuple or dictionary.

Code #6 :

double call_func(PyObject *func, double x, double y)
    {
        PyObject *args;
        PyObject *kwargs;
          
        /* Build arguments */
        args = Py_BuildValue("(dd)", x, y);
        kwargs = NULL;
        /* Call the function */
        result = PyObject_Call(func, args, kwargs);
        Py_DECREF(args);
        Py_XDECREF(kwargs);
         
          
        /* Check for Python exceptions (if any) */
        if (PyErr_Occurred())
        {
            PyErr_Print();
            goto fail;
        }
          
    fail:
        PyGILState_Release(state);
        abort();
          
    }

Внимание компьютерщик! Укрепите свои основы с помощью базового курса программирования Python и изучите основы.

Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.