Kurs języka Python

Wykład 14.

● Rozszerzenia Pythona (C API)

● Osadzanie Pythona

● Jython

● IronPython

Pierwszy program

Moduł z funkcją obliczającą średnią arytmetyczną elementów listy

modul.c

#include <python2.4/Python.h>

Nagłówki

extern PyObject * mean(PyObject *, PyObject *); PyObject * mean(PyObject * self, PyObject * args)

{

Deklaracje zmiennych

int suma = 0;

int n, i;

PyObject * res;

PyObject * item;

PyObject * lista;

Argumenty wywołania

lista = PySequence_ITEM(args, 0);

if (!PyList_Check(lista)) printf("Nie jest listą\n");

Przetwarzanie listy

lista = PySequence_ITEM(args, 0);

n = PyList_Size(lista);

Przetwarzanie listy, cd

for (i = 0; i < n; i++) {

item = PyList_GetItem(lista, i);

if (!PyInt_Check(item)) continue;

suma += PyInt_AsLong(item);

}

Zwrócenie wartości

res = Py_BuildValue("i", suma/n);

Py_INCREF(res);

return res;

}

Rejestrowanie funkcji

static PyMethodDef modulik[] = {

{ "mean", mean, METH_VARARGS },

{ NULL, NULL }

};

Inicjowanie modułu

void initmodulik(void) {

Py_InitModule("modulik", modulik);

}

Trochę teori

Zagadnienia:

● Dostęp do obcych typów

● Przekazywanie argumentów i zwracanie

wartości

● Tworzenie nowych wartości

● Wyjątki

● Zarządzanie pamięcią

Dostęp do typów

Wszystkow Pythonie jest obiektem

Makra dostępu do obiektów

● Dostęp do elementów

PyObject* PyObject_GetItem(

PyObject *o, PyObject *key)

int PyObject_SetItem(

PyObject *o, PyObject *key, PyObject *v)

● Zamiany na string

PyObject* PyObject_Str(PyObject *o)

● Rozmiar

Py_ssize_t PyObject_Length(PyObject *o)

Dostęp do konkretnych typów

int PyNumber_Check( PyObject *o)

PyObject* PyNumber_Add(

PyObject *o1, PyObject *o2)

Dostęp do sekwencji

PyObject* PySequence_GetItem(

PyObject *o, Py_ssize_t i)

PyObject* PySequence_ITEM(

PyObject *o, Py_ssize_t i)

int PySequence_SetItem(

PyObject *o, Py_ssize_t i, PyObject *v)

Dostęp do list

Podobnie jak w sekwencjach

int PyList_Insert(PyObject *list,

Py_ssize_t index, PyObject *item)

int PyList_Append(PyObject *list,

PyObject *item)

Tworzenie nowych obiektów

PyObject* PyInt_FromLong( long ival)

PyObject* Py_False

PyObject* Py_True

PyObject* PyList_New( Py_ssize_t len)

PyObject* PyString_FromString( const char *v)

Zarządzanie pamięcią

● Każdy obiekt ma licznik odwołań zwiększany za każdym przypisaniem

● Jeśli licznik jest równy zero obiekt jest usuwany z pamięci

● W programach w C trzeba dbać o aktualizację licznika

Zarządzanie pamięcią

void Py_INCREF(PyObject *o)

void Py_DECREF(PyObject *o)

Przypomnienie

res = Py_BuildValue("i", suma/n);

Py_INCREF(res);

return res;

Zwrócenie wartości None

PyObject* Py_None

---

Py_INCREF(Py_None);

return Py_None;

---

Py_RETURN_NONE

Parsowanie argumentów

Argumenty wywołania przekazywane są jako

pojedyncza sekwencja, więc można kolejno je

odczytywać.

Py_ssize_t PySequence_Size(PyObject *o)

PyObject* PySequence_GetItem(

PyObject *o, Py_ssize_t i)

Parsowanie argumentów

int PyArg_ParseTuple(Py_Object *, const char *, ...)

Przykład

int i;

int j;

const char * str;

PyArg_ParseTuple(arg, “i s”, &i, &j, &str);

Wyjątki

● int PyErr_Occurred()

● Stałe dla typowych wyjątków

Przykład

item = PyObject_GetItem(dict, key);

if (item == NULL)

if (!PyErr_ExceptionMatches(PyExc_KeyError)) PyErr_Clear();

Zgłoszenie wyjątku

PyObject* PyErr_SetFromErrno(PyObject *type)

Jak skompilować i zainstalować własną bibliotekę

from distutils.core import setup, Extension

module1 = Extension('modulik',

sources = ['test.c'])

setup (name = 'MyPackage',

version = '1.0',

description = 'Pakiet demonstracyjny',

ext_modules = [module1])

Kompilacja i wykonanie

$ python setup.py build

$ python setup.py instal

Osadzanie Pythona w C

Py_Initialize();

PyRun_SimpleString("i = 2");

PyRun_SimpleString("i = i*i\nprint i"); Py_Finalize();

Wykonanie pliku

Py_Initialize();

FILE * f = fopen("test.py", "r"); PyRun_SimpleFile(f, "co to");

Py_Finalize();

Kompilacja

gcc -lpython2.4 test.c

Jython - instalacja

java jython_21

Wynik

Exception in thread "main"

java.lang.ClassFormatError: Extra bytes at the end of class file jython_21

IronPython

mono ipy.exe

mono ipy.exe plik.py

Na koniec

Dziś nie będzie żadnego zdjęcia