Главная страница
Навигация по странице:

  • Формат Тип в языке Python Тип аргумента в языке C

  • Имя типа в языке C Тип в языке Python

  • Формат Описание

  • Преобразование типов данных языка C в типы языка Python

  • PyObject *Py_BuildValue(char * format , ...)

  • Формат Тип в языке Python Тип в языке C Описание

  • Добавление значений в модуль

  • Имя в языке C Исключение в языке Python

  • Макроопределение Описание

  • справочник по Python. мм isbn 9785932861578 9 785932 861578


    Скачать 4.21 Mb.
    Названиемм isbn 9785932861578 9 785932 861578
    Анкорсправочник по Python
    Дата08.05.2022
    Размер4.21 Mb.
    Формат файлаpdf
    Имя файлаBizli_Python-Podrobnyy-spravochnik.440222.pdf
    ТипСправочник
    #518195
    страница67 из 82
    1   ...   63   64   65   66   67   68   69   70   ...   82
    745
    Э
    ти спецификаторы должны использоваться только для обработки строк байтов и не способны работать со строками Юникода. Спецификатор “y” может принимать только строки байтов, не содержащие символы NULL.
    В табл. 26.3 перечислены спецификаторы, которые принимают произволь- ные объекты языка Python и возвращают результат типа PyObject *. Они иногда используются в расширениях на языке C, которые должны обра-
    C, которые должны обра-
    , которые должны обра- батывать объекты языка Python, более сложные, чем простые числа или строки, такие как экземпляры классов или словари.
    Таблица 26.3. Преобразование объектов языка Python
    и соответствующие типы аргументов функций PyArg_Parse*
    Формат
    Тип в языке Python
    Тип аргумента в языке C
    “O”
    Любой
    PyObject **
    r
    “O!”
    Любой
    PyTypeObject *
    type, PyObject **r
    “O&”
    Любой int (*
    converter)(PyObject *, void *), void *r
    “S”
    Строка
    PyObject **
    r
    “U”
    Строка Юникода
    PyObject **
    r
    Спецификаторы “O”, “S” и “U” возвращают объекты Python типа PyObject *.
    Спецификаторы “S” и “U” ограничиваются объектами строк и строк Юни- кода соответственно.
    Спецификатор “O!” требует наличия двух аргументов: указателя на объект типа языка Python и указателя PyObject * на указатель, который ссылается на местоположение объекта в памяти. Если тип объекта не соответствует объекту типа, возбуждается исключение TypeError. Например:
    /* Преобразование списка аргументов */
    PyObject *listobj;
    PyArg_ParseTuple(args,”O!”, &PyList_Type, &listobj);
    В следующем списке перечислены имена типов языка C, соответствующие некоторым контейнерным типам в языке Python, которые часто участвуют в подобных преобразованиях.
    Имя типа в языке C
    Тип в языке Python
    PyList_Type list
    PyDict_Type dict
    PySet_Type set
    PyFrozenSet_Type frozen_set
    PyTuple_Type tuple
    PySlice_Type slice
    PyByteArray_Type bytearray

    746
    Глава 26. Расширение и встраивание интерпретатора Python
    Спецификатор “O&” принимает два аргумента (converter, addr) и преобразует
    PyObject *
    в тип данных языка C. Аргумент converter – это указатель на функцию с сигнатурой int converter(PyObject *obj, void *addr), где obj – это полученный объект на языке Python, а addr – адрес, который передается вторым аргументом функции PyArg_ParseTuple(). В случае успеха функция
    converter()
    должна возвращать 1, и 0 – в случае ошибки. Кроме того, в слу- чае ошибки функция converter() должна возбудить исключение. Преобразо- вания такого типа могут использоваться для отображения объектов языка
    Python, таких как списки или кортежи, в структуры данных на языке C.
    Например, ниже приводится одна из возможных реализаций функции- обертки py_distance() из ранее рассматривавшегося программного кода:
    /* Преобразует кортеж в структуру Point. */
    int convert_point(PyObject *obj, void *addr) {
    Point *p = (Point *) addr;
    return PyArg_ParseTuple(obj,”ii”, &p->x, &p->y);
    }
    PyObject *py_distance(PyObject *self, PyObject *args) {
    Point p1, p2;
    double result;
    if (!PyArg_ParseTuple(args,”O&O&”,
    convert_point, &p1, convert_point, &p2)) {
    return NULL;
    }
    result = distance(&p1,&p2);
    return Py_BuildValue(“d”,result);
    }
    Наконец, аргумент format может содержать дополнительные модификато- ры, имеющие отношение к распаковыванию кортежей, строкам докумен- тирования, сообщениям об ошибках и значениям аргументов по умолча- нию. Эти модификаторы перечислены в следующем списке:
    Формат
    Описание
    “(items)”
    Описывает порядок распаковывания кортежей объектов. items содер- жит спецификаторы формата.
    “|”
    Начало списка необязательных аргументов.
    “:”
    Конец списка аргументов. Остальной текст обозначает имя функции.
    “;”
    Конец списка аргументов. Остальной текст – это сообщение об ошибке.
    Модификатор “(items)” распаковывает значения, переданные в виде кор- тежа языка Python. Это может пригодиться для отображения кортежей в простые структуры на языке C. Например, ниже приводится еще одна возможная реализация функции-обертки py_distance():
    PyObject *py_distance(PyObject *self, PyObject *args) {
    Point p1, p2;
    double result;
    if (!PyArg_ParseTuple(args,”(dd)(dd)”,
    &p1.x, &p1.y, &p2.x, &p2.y)) {

    Модули расширений
    747
    return NULL;
    }
    result = distance(&p1,&p2);
    return Py_BuildValue(“d”,result);
    }
    М
    одификатор “|” указывает, что все последующие аргументы являются необязательными. Этот модификатор может появляться в строке формата только один раз и не может быть вложенным. Модификатор “:” отмечает конец списка аргументов. Любой текст, следующий за ним, будет интер- претироваться, как имя функции для вывода в сообщениях об ошибках.
    Модификатор “;” также отмечает конец списка аргументов. Любой текст, следующий за ним, будет интерпретироваться, как текст сообщения об ошибке. Имейте в виду, что допускается использовать только какой-то один из модификаторов : и ;. Ниже приводятся несколько примеров:
    PyArg_ParseTuple(args,”ii:gcd”, &x, &y);
    PyArg_ParseTuple(args,”ii; gcd requires 2 integers”, &x, &y);
    ёёё
    /* Преобразование с двумя необязательными аргументами */
    PyArg_ParseTuple(args,”s|s”, &buffer, &delimiter);
    Преобразование типов данных языка C
    в типы языка Python
    Для преобразования значений переменных языка C в объекты языка Py-
    C в объекты языка Py- в объекты языка Py-
    Py- thon используется следующая функция:
    PyObject *Py_BuildValue(char *format, ...)
    Конструирует объект Python на основе последовательности переменных языка C. Аргумент format – это строка, описывающая требуемое преобра- зование. Остальные аргументы функции – значения переменных языка C, участвующие в преобразовании.
    Спецификаторы формата, которые можно использовать в аргументе format, похожи на спецификаторы, используемые в функциях PyArg_ParseTuple*(), как видно из табл. 26.4.
    Таблица 26.4. Спецификаторы формата для функции Py_BuildValue()
    Формат
    Тип в языке Python
    Тип в языке C
    Описание
    “”
    None void
    Ничего.
    “a”
    Строка char *
    Строка, завершающаяся сим- волом NULL. Если указатель на строку содержит значение
    NULL
    , возвращает значение None.
    “s#”
    Строка char *
    , int
    Строка и ее длина. Может содер- жать байты со значением ‘\x00’.
    Если указатель на строку содер- жит значение
    NULL
    , возвращает значение None.

    748
    Глава 26. Расширение и встраивание интерпретатора Python
    Формат
    Тип в языке Python
    Тип в языке C
    Описание
    “y”
    Строка байтов char *
    То же, что и “s”, но возвращает строку байтов.
    “y#”
    Строка байтов char *
    , int
    То же, что и “s#”, но возвращает строку байтов.
    “z”
    Строка или None char *
    То же, что и “s”.
    “z#”
    Строка или None char *
    , int
    То же, что и “s#”.
    “u”
    Строка Юникода
    Py_UNICODE *
    Строка Юникода, завершаю- щаяся символом NULL. Если указатель на строку содержит значение
    NULL
    , возвращает зна- чение None.
    “u#”
    Строка Юникода
    Py_UNICODE *
    Строка Юникода и ее длина.
    “U”
    Строка Юникода char *
    Преобразует строку языка C, завершающуюся символом NULL, в строку Юникода.
    “U#”
    Строка Юникода char *
    , int
    Преобразует строку языка C в строку Юникода.
    “b”
    Целое число char
    8-битное целое.
    “B”
    Целое число unsigned char
    8-битное целое без знака.
    “h”
    Целое число short
    16-битное короткое целое.
    “H”
    Целое число unsigned short
    16-битное короткое целое без знака.
    “i”
    Целое число int
    Целое число.
    “I”
    Целое число unsigned int
    Целое число без знака.
    “l”
    Целое число long
    Длинное целое число.
    “L”
    Целое число unsigned long
    Длинное целое число без знака.
    “k”
    Целое число long long
    Длинное целое типа long long.
    “K”
    Целое число unsigned long long
    Длинное целое типа long long без знака.
    “n”
    Целое число
    Py_ssize_t
    Тип size в языке Python.
    “c”
    Строка char
    Единственный символ. Создает строку языка Python с одним символом.
    “f”
    Число с плавающей точкой float
    Число с плавающей точкой оди- нарной точности.
    “d”
    Число с плавающей точкой double
    Число с плавающей точкой двойной точности.
    “D”
    Комплексное число
    Py_complex
    Комплексное число.
    Таблица 26.4 (продолжение)

    Модули расширений
    749
    Формат
    Тип в языке Python
    Тип в языке C
    Описание
    “O”
    Л
    юбой
    PyObject *
    Любой объект языка Python.
    Объект не изменяется, за ис- ключением его счетчика ссы- лок, который увеличивается на 1. Если передается пустой указатель, возвращает также пустой указатель. Это удобно, когда ошибка возникла где-то в одном месте, а в другом необ- ходимо продолжить ее распро- странение.
    “O&”
    Любой функция пре- пре- пре- образования, любой
    Данные, полученные от про- граммного кода на языке C, обрабатываются функцией пре- образования.
    “S”
    Строка
    PyObject *
    То же, что и “O”.
    “N”
    Любой
    PyObject *
    То же, что и “O”, за исключением того, что счетчик ссылок объек- та не увеличивается.
    “(
    items)”
    Кортеж
    vars
    Создает кортеж элементов items.
    items
    – строка со спецификато- рами формата из этой таблицы.
    vars
    – список переменных языка
    C, соответствующих специфика-
    , соответствующих специфика- торам в items.
    “[
    items]”
    Список
    vars
    Создает список элементов items.
    items –
    строка со спецификато- рами формата. vars – список переменных языка C, соот- ветствующих спецификаторам в items.
    “{
    items}”
    Словарь
    vars
    Создает словарь элементов items.
    Ниже приводятся несколько примеров создания значений различных ти- пов:
    Py_BuildValue(“”) None
    Py_BuildValue(“i”,37) 37
    Py_BuildValue(“ids”,37,3.4,”hello”) (37, 3.5, “hello”)
    Py_BuildValue(“s#”,”hello”,4) “hell”
    Py_BuildValue(“()”) ()
    Py_BuildValue(“(i)”,37) (37,)
    Py_BuildValue(“[ii]”,1,2) [1,2]
    Py_BuildValue(“[i,i]”,1,2) [1,2]
    Py_BuildValue(“{s:i,s:i}”,”x”,1,”y”,2) {‘x’:1, ‘y’:2}
    Строки Юникода создаются из данных типа char *; это означает, что ис- ходные данные представляют собой последовательность байтов в коди- ровке по умолчанию (обычно UTF-8). Данные автоматически декодируют-
    (обычно UTF-8). Данные автоматически декодируют- обычно UTF-8). Данные автоматически декодируют-
    UTF-8). Данные автоматически декодируют-
    Данные автоматически декодируют-

    750
    Глава 26. Расширение и встраивание интерпретатора Python ся в строки Юникода при передаче программному коду на языке Python.
    Единственное исключение из этого правила составляют спецификаторы
    “y”
    и “y#”, которые возвращают обычные строки байтов.
    Добавление значений в модуль
    В функции инициализации модуля расширения часто производится до- бавление констант и других значений. Для этой цели могут использоваться следующие функции:
    int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)
    Добавляет в модуль новое значение. Аргумент name определяет имя значе- ния, а аргумент value – объект Python, содержащий значение. Значения можно создавать с помощью функции Py_BuildValue().
    int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
    Добавляет в модуль целочисленное значение.
    void
    PyModule_AddStringConstant(PyObject *module, const char *name, const char
    *value)
    Добавляет в модуль строковое значение. В аргументе value должна переда- ваться строка, заканчивающаяся символом NULL.
    void PyModule_AddIntMacro(PyObject *module, macro)
    Добавляет в модуль целочисленное значение макроопределения. Аргумент
    macro
    должен быть именем макроопределения препроцессора.
    void PyModule_AddStringMacro(PyObject *module, macro)
    Добавляет в модуль строковое значение макроопределения.
    Обработка ошибок
    Модули расширений сообщают об ошибках, возвращая интерпретатору значение NULL. Перед тем как вернуть NULL, модуль должен определить ис- ключение с помощью одной из следующих функций:
    void PyErr_NoMemory()
    Возбуждает исключение MemoryError.
    void PyErr_SetFromErrno(PyObject *exc)
    Возбуждает исключение exc. В аргументе exc передается объект исключе- ния. Код ошибки для исключения извлекается из переменной errno в би- блиотеке языка C.
    void PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
    То же, что и PyErr_SetFromErrno(), но добавляет в исключение еще и имя фай- ла.
    void PyErr_SetObject(PyObject *exc, PyObject *val)
    Возбуждает исключение exc. В аргументе exc передается объект исключе- ния, а в аргументе val – объект со значениями атрибутов исключения.

    Модули расширений
    751
    void PyErr_SetString(PyObject *exc, char *msg)
    Возбуждает исключение exc. В аргументе exc передается объект исключе- ния, а в аргументе msg – сообщение, описывающее ошибку.
    В аргументе exc допускается передавать одно из следующих значений:
    Имя в языке C
    Исключение в языке Python
    PyExc_ArithmeticError
    ArithmeticError
    PyExc_AssertionError
    AssertionError
    PyExc_AttributeError
    AttributeError
    PyExc_EnvironmentError
    EnvironmentError
    PyExc_EOFError
    EOFError
    PyExc_Exception
    Exception
    PyExc_FloatingPointError
    FloatingPointError
    PyExc_ImportError
    ImportError
    PyExc_IndexError
    IndexError
    PyExc_IOError
    IOError
    PyExc_KeyError
    KeyError
    PyExc_KeyboardInterrupt
    KeyboardInterrupt
    PyExc_LookupError
    LookupError
    PyExc_MemoryError
    MemoryError
    PyExc_NameError
    NameError
    PyExc_NotImplementedError
    NotImplementedError
    PyExc_OSError
    OSError
    PyExc_OverflowError
    OverflowError
    PyExc_ReferenceError
    ReferenceError
    PyExc_RuntimeError
    RuntimeError
    PyExc_StandardError
    StandardError
    PyExc_StopIteration
    StopIteration
    PyExc_SyntaxError
    SyntaxError
    PyExc_SystemError
    SystemError
    PyExc_SystemExit
    SystemExit
    PyExc_TypeError
    TypeError
    PyExc_UnicodeError
    UnicodeError
    PyExc_UnicodeEncodeError
    UnicodeEncodeError
    PyExc_UnicodeDecodeError
    UnicodeDecodeError
    PyExc_UnicodeTranslateError
    UnicodeTranslateError

    752
    Глава 26. Расширение и встраивание интерпретатора Python
    Имя в языке C
    Исключение в языке Python
    PyExc_ValueError
    ValueError
    PyExc_WindowsError
    WindowsError
    PyExc_ZeroDivisionError
    ZeroDivisionError
    Н
    иже перечислены функции, которые могут использоваться для полу- чения от интерпретатора информации о наличии исключения или чтобы сбросить исключение:
    void PyErr_Clear()
    Сбрасывает ранее возбужденные исключения.
    PyObject *PyErr_Occurred()
    Проверяет, было ли возбуждено исключение. Если исключение было воз- буждено, возвращает текущее значение исключения. В противном случае возвращает NULL.
    int PyErr_ExceptionMatches(PyObject *exc)
    Проверяет, соответствует ли текущее исключение исключению exc. Если соответствует, возвращает 1, если не соответствует – 0. При сопоставлении исключений эта функция применяет правила, определяемые языком Py-
    Py- thon. То есть exc может быть суперклассом текущего исключения или кор- тежем классов исключений.
    Ниже приводится пример реализации блока try-except на языке C:
    /* Выполнить некоторые операции над объектами языка Python */
    if (PyErr_Occurred()) {
    if (PyErr_ExceptionMatches(PyExc_ValueError)) {
    /* выполнить действия по восстановлению после ошибки */
    ...
    PyErr_Clear();
    return result; /* Допустимый PyObject * */
    } else {
    return NULL; /* Передать исключение интерпретатору */
    }
    }
    Подсчет ссылок
    В отличие от программ, написанных на языке Python, расширения на язы-
    Python, расширения на язы-
    , расширения на язы- ке C имеют возможность манипулировать счетчиками ссылок объектов Py-
    C имеют возможность манипулировать счетчиками ссылок объектов Py- имеют возможность манипулировать счетчиками ссылок объектов Py-
    Py- thon. Делается это с помощью следующих макроопределений, каждое из которых применяется к объектам типа PyObject *.
    Макроопределение
    Описание
    Py_INCREF(
    obj)
    Увеличивает счетчик ссылок объекта, на который ссылает- ся указатель obj. Указатель не должен быть пустым.
    (продолжение)

    Модули расширений
    753
    Py_DECREF(
    obj)
    У
    меньшает счетчик ссылок объекта, на который ссылается указатель obj. Указатель не должен быть пустым.
    Py_XINCREF(
    obj)
    Увеличивает счетчик ссылок объекта, на который ссылает- ся указатель obj. Указатель может быть пустым.
    Py_XDECREF(
    obj)
    Уменьшает счетчик ссылок объекта, на который ссылается указатель obj. Указатель может быть пустым.
    Манипулирование счетчиками ссылок объектов языка Python из про-
    Python из про- из про- граммного кода на языке C – это достаточно тонкая тема, поэтому читате-
    C – это достаточно тонкая тема, поэтому читате-
    – это достаточно тонкая тема, поэтому читате- лям настоятельно рекомендуется прочитать документ «Extending and Em-
    Extending and Em- and Em- and Em-
    Em-
    Em- bedding the Python Interpreter» (Расширение и встраивание интерпретато- the Python Interpreter» (Расширение и встраивание интерпретато- the Python Interpreter» (Расширение и встраивание интерпретато-
    Python Interpreter» (Расширение и встраивание интерпретато-
    Python Interpreter» (Расширение и встраивание интерпретато-
    Interpreter» (Расширение и встраивание интерпретато-
    Interpreter» (Расширение и встраивание интерпретато-
    » (Расширение и встраивание интерпретато- ра Python), по адресу http://docs.python.org/extending, прежде чем предпри- нимать что-либо. Как правило, в расширениях на языке C не приходится беспокоиться о счетчиках ссылок на объекты, за исключением следующих случаев:
    • Если ссылка на объект Python сохраняется для последующего исполь-
    Python сохраняется для последующего исполь- сохраняется для последующего исполь- зования в структуре на языке C, счетчик ссылок необходимо увеличить.
    Аналогично при удалении ссылки, сохраненной ранее, счетчик ссылок необходимо уменьшить.
    • При управлении контейнерными объектами языка Python (списками, словарями и другими) из программного кода на языке C может потребо-
    C может потребо- может потребо- ваться реализовать управление счетчиками ссылок отдельных элемен- тов. Например, высокоуровневые операции, которые извлекают или до- бавляют элементы в контейнер, обычно увеличивают счетчик ссылок.
    Обычно ошибки при работе со счетчиками ссылок проявляются в аварий- ном завершении интерпретатора при попытке использовать расширение (вы забыли увеличить счетчик ссылок) или в виде утечек памяти при исполь- зовании функций из расширения (вы забыли уменьшить счетчик ссылок).
    1   ...   63   64   65   66   67   68   69   70   ...   82


    написать администратору сайта