- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Язык программирования Python - Роман Сузи
Шрифт:
Интервал:
Закладка:
Под протоколом здесь понимается набор методов, которые должен поддерживать тот или иной класс для организации операций со своими экземплярами. Эти методы доступны не только из Python (например, len(a) дает длину последовательности), но и из кода на C (PySequence_Length()).
Написание модуля расширения
Если необходимость встроить Python в программу возникает нечасто, то его расширение путем написания модулей на C/C++ - довольно распространенная практика. Изначально Python был нацелен на возможность расширения, поэтому в настоящий момент очень многие C/C++-библиотеки имеют привязки к Python.
Привязка к Python, хотя и может быть несколько автоматизирована, все же это процесс творческий. Дело в том, что если предполагается интенсивно использовать библиотеку в Python, ее привязку желательно сделать как можно более тщательно. Возможно, в ходе привязки будет сделана объектно–ориентированная надстройка или другие архитектурные изменения, которые позволят упростить использование библиотеки.
В качестве примера можно привести выдержку из исходного кода модуля md5, который реализует функцию для получения md5–дайджеста. Модуль приводится в целях иллюстрации (то есть, с сокращениями). Модуль вводит собственный тип данных, MD5Type, поэтому можно увидеть не только реализацию функций, но и способ описания встроенного типа. В рамках этого курса не изучить все тонкости программирования модулей расширения, главное понять дух этого занятия. На комментарии автора курса лекций указывает двойной слэш //:
// заголовочные файлы
#include "Python.h"
#include "md5.h"
// В частности, в заголовочном файле md5.h есть следующие определения:
// typedef unsigned char *POINTER;
// typedef unsigned int UINT4;
// typedef struct {
// UINT4 state[4]; /* state (ABCD) */
// UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
// unsigned char buffer[64]; /* input buffer */
// } MD5_CTX;
// Структура объекта MD5type
typedef struct {
PyObject_HEAD
MD5_CTX md5; /* the context holder */
} md5object;
// Определение типа объекта MD5type
static PyTypeObject MD5type;
// Макрос проверки типа MD5type
#define is_md5object(v) ((v)->ob_type == &MD5type)
// Порождение объекта типа MD5type
static md5object * newmd5object(void) {
md5object *md5p;
md5p = PyObject_New(md5object, &MD5type);
if (md5p == NULL)
return NULL; // не хватило памяти
MD5Init(&md5p->md5); // инициализация
return md5p;
}
// Определения методов
// Освобождение памяти из–под объекта
static void md5_dealloc(md5object *md5p) { PyObject_Del(md5p); }
static PyObject * md5_update(md5object *self, PyObject *args) {
unsigned char *cp;
int len;
// разбор строки аргументов. Формат указывает следующее:
// s# - один параметр, строка (заданная указателем и длиной)
// : - разделитель
// update — название метода
if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
return NULL;
MD5Update(&self->md5, cp, len);
// Даже возврат None требует увеличения счетчика ссылок
Py_INCREF(Py_None);
return Py_None;
}
// Строка документации метода update
PyDoc_STRVAR(update_doc,
"update (arg)n
n
Update the md5 object with the string arg. Repeated calls aren
equivalent to a single call with the concatenation of all then
arguments.");
// Метод digest
static PyObject * md5_digest(md5object *self) {
MD5_CTX mdContext;
unsigned char aDigest[16];
/* make a temporary copy, and perform the final */
mdContext = self->md5;
MD5Final(aDigest, &mdContext);
// результат возвращается в виде строки
return PyString_FromStringAndSize((char *)aDigest, 16);
}
// и строка документации
PyDoc_STRVAR(digest_doc, "digest() -> stringn ...");
static PyObject * md5_hexdigest(md5object *self) {
// Реализация метода на C
}
PyDoc_STRVAR(hexdigest_doc, "hexdigest() -> stringn...");
// Здесь было определение метода copy()
// Методы объекта в сборе.
// Для каждого метода указывается название, имя метода на C
// (с приведением к типу PyCFunction), способ передачи аргументов:
// METH_VARARGS (переменное кол–во) или METH_NOARGS (нет аргументов)
// В конце массива — метка окончания спиcка аргументов.
static PyMethodDef md5_methods[] = {
{"update", (PyCFunction)md5_update, METH_VARARGS, update_doc},
{"digest", (PyCFunction)md5_digest, METH_NOARGS, digest_doc},
{"hexdigest", (PyCFunction)md5_hexdigest, METH_NOARGS, hexdigest_doc},
{"copy", (PyCFunction)md5_copy, METH_NOARGS, copy_doc},
{NULL, NULL} /* sentinel */
};
// Атрибуты md5–объекта обслуживает эта функция, реализуя метод
// getattr.
static PyObject * md5_getattr(md5object *self, char *name) {
// атрибут–данное digest_size
if (strcmp(name, "digest_size") == 0) {
return PyInt_FromLong(16);
}
// поиск атрибута–метода ведется в списке
return Py_FindMethod(md5_methods, (PyObject *)self, name);
}
// Строка документации к модулю md5
PyDoc_STRVAR(module_doc, "This module implements ...");
// Строка документации к классу md5
PyDoc_STRVAR(md5type_doc, "An md5 represents the object...");
// Структура для объекта MD5type с описаниями для интерпретатора
static PyTypeObject MD5type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"md5.md5", /*tp_name*/
sizeof(md5object), /*tp_size*/
0, /*tp_itemsize*/
/* methods */
(destructor)md5_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)md5_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
0, /*tp_xxx4*/
md5type_doc, /*tp_doc*/
};
// Функции модуля md5:
// Функция new() для получения нового объекта типа md5type
static PyObject * MD5_new(PyObject *self, PyObject *args) {
md5object *md5p;
unsigned char *cp = NULL;
int len = 0;
// Разбор параметров. Здесь вертикальная черта
// в строке формата означает окончание
// списка обязательных параметров.
// Остальное — как и выше: s# - строка, после : — имя
if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
return NULL;
if ((md5p = newmd5object()) == NULL)
return NULL;
// Если был задан параметр cp:
if (cp)
MD5Update(&md5p->md5, cp, len);
return (PyObject *)md5p;
}
// Строка документации для new()
PyDoc_STRVAR(new_doc, "new([arg]) -> md5 object ...");
// Список функций, которые данный модуль экспортирует
static PyMethodDef md5_functions[] = {
{"new", (PyCFunction)MD5_new, METH_VARARGS, new_doc},
{"md5", (PyCFunction)MD5_new, METH_VARARGS, new_doc},
{NULL, NULL} /* Sentinel */
};
// Следует заметить, что md5 — то же самое, что new. Эта функция оставлена для
// обратной совместимости со старым модулем md5
// Инициализация модуля
PyMODINIT_FUNC initmd5(void) {
PyObject *m, *d;
MD5type.ob_type = &PyType_Type;
// Инициализируется модуль
m = Py_InitModule3("md5", md5_functions, module_doc);
// Получается словарь с именами модуля
d = PyModule_GetDict(m);
// Добавляется атрибут MD5Type (тип md5–объекта) к словарю
PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
// Добавляется целая константа digest_size к модулю
PyModule_AddIntConstant(m, "digest_size", 16);
}
На основе этого примера можно строить собственные модули расширения, ознакомившись с документацией по C/API и документом «Extending and Embedding» («Расширение и встраивание») из стандартной поставки Python. Перед тем, как приступать к созданию своего модуля, следует убедиться, что это целесообразно: подходящего модуля еще не создано и реализация в виде чистого Python неэффективна. Если создан действительно полезный модуль, его можно предложить для включения в поставку Python. Для этого нужно просто связаться с кем–нибудь из разработчиков по электронной почте или предложить модуль в виде «патча» через http://sourceforge.net.
Пример встраивания интерпретатора в программу на C
Интерпретатор Python может быть встроен в программу на C с использованием C API. Это лучше всего демонстрирует уже работающий пример: