Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by haas.homelinux.net...

Inhaltsverzeichnis
1 Einleitung
2 Überblick über Python
3 Die Arbeit mit Python
4 Der interaktive Modus
5 Grundlegendes zu Python-Programmen
6 Kontrollstrukturen
7 Das Laufzeitmodell
8 Basisdatentypen
9 Benutzerinteraktion und Dateizugriff
10 Funktionen
11 Modularisierung
12 Objektorientierung
13 Weitere Spracheigenschaften
14 Mathematik
15 Strings
16 Datum und Zeit
17 Schnittstelle zum Betriebssystem
18 Parallele Programmierung
19 Datenspeicherung
20 Netzwerkkommunikation
21 Debugging
22 Distribution von Python-Projekten
23 Optimierung
24 Grafische Benutzeroberflächen
25 Python als serverseitige Programmiersprache im WWW mit Django
26 Anbindung an andere Programmiersprachen
27 Insiderwissen
28 Zukunft von Python
A Anhang
Stichwort

Download:
- ZIP, ca. 4,8 MB
Buch bestellen
Ihre Meinung?

Spacer
 <<   zurück
Python von Peter Kaiser, Johannes Ernesti
Das umfassende Handbuch - Aktuell zu Python 2.5
Buch: Python

Python
gebunden, mit CD
819 S., 39,90 Euro
Galileo Computing
ISBN 978-3-8362-1110-9
Pfeil 26 Anbindung an andere Programmiersprachen
  Pfeil 26.1 Dynamisch ladbare Bibliotheken – ctypes
    Pfeil 26.1.1 Ein einfaches Beispiel
    Pfeil 26.1.2 Die eigene Bibliothek
    Pfeil 26.1.3 Schnittstellenbeschreibung
    Pfeil 26.1.4 Verwendung des Moduls
  Pfeil 26.2 Schreiben von Extensions
    Pfeil 26.2.1 Ein einfaches Beispiel
    Pfeil 26.2.2 Exceptions
    Pfeil 26.2.3 Erzeugen der Extension
    Pfeil 26.2.4 Reference Counting
  Pfeil 26.3 Python als eingebettete Skriptsprache
    Pfeil 26.3.1 Ein einfaches Beispiel
    Pfeil 26.3.2 Ein komplexeres Beispiel
    Pfeil 26.3.3 Python-API-Referenz


Galileo Computing - Zum Seitenanfang

26.3 Python als eingebettete Skriptsprache  Zur nächsten ÜberschriftZur vorigen Überschrift

In den vorangegangenen Abschnitten haben Sie Möglichkeiten kennengelernt, in C geschriebene Programmteile von einem Python-Programm aus aufzurufen und somit beispielsweise laufzeitkritische Teile in ein C-Programm auszulagern.

In diesem Kapitel soll der entgegengesetzte Weg beschritten werden: Wir möchten Python-Programme aus einem C-Programm heraus ausführen können, Python also als eine Art eingebettete Scriptsprache (engl. embedded script language) verwenden. [Ein Beispiel für eine solche eingebettete Skriptsprache ist Lua, die besonders häufig als Skriptsprache für Computerspiele eingesetzt wird. ] Auf diese Weise können wir bestimmte Teile des Programms in Python schreiben, für die Python aufgrund seiner Flexibilität einfach besser geeignet ist.


Galileo Computing - Zum Seitenanfang

26.3.1 Ein einfaches Beispiel  Zur nächsten ÜberschriftZur vorigen Überschrift

Zum Einstieg soll ein C-Programm erstellt werden, das ein möglichst simples Python-Programm ausführt. Dieses Python-Programm soll lediglich ein bisschen Text und eine Zufallszahl auf dem Bildschirm ausgeben.

Das folgende C-Programm führt ein solches Python-Script aus:

#include <Python.h>
const char *programm = "import random\n" "print 'Guten Tag, die Zahl ist:', random.randint(0, 100)\n" "print 'Das war ... Python'\n";
int main(int argc, char *argv[]) { Py_Initialize(); PyRun_SimpleString(programm); Py_Finalize(); }

Zunächst wird die Header-Datei der Python API eingebunden. Sie sehen, dass sowohl zum Erweitern als auch zum Einbetten von Python dieselbe API verwendet wird. Danach wird der String programm angelegt, der den Python-Code enthält, der später ausgeführt werden soll.

In der Hauptfunktion main wird der Python-Interpreter zuerst durch Aufruf von Py_Initialize initialisiert. Danach wird das zuvor im String programm abgelegte Python-Script durch Aufruf der Funktion PyRun_SimpleString ausgeführt und der Interpreter schlussendlich durch die Funktion Py_Finalize wieder beendet.

Statt der Funktion PyRun_SimpleString hätte auch die Funktion PyRun_Simple File aufgerufen werden können, um den Python-Code aus einer Datei zu lesen.

Wichtig ist, dass dem Compiler das Verzeichnis bekannt ist, in dem die Header-Datei Python.h liegt. Außerdem muss das Programm gegen die Python API gelinkt werden. Diese ist als dynamische Bibliothek python25.lib im Unterordner lib Ihrer Python-Installation zu finden. [Diese Angabe bezieht sich auf Windows. Unter Linux wird die Bibliothek in den meisten Fällen in das Verzeichnis für systemweite Bibliotheken /usr/lib installiert. Beim Linken Ihres Programms mit dem GCC können Sie die Python 2.5-Bibliothek mit der Option -lpython2.5 einbinden. ] Wenn sowohl das Kompilieren als auch das Linken ohne Probleme vonstatten gegangen ist, werden Sie feststellen, dass das Programm tatsächlich funktioniert:

Guten Tag, die Zufallszahl ist: 64 
Das war ... Python

Sie sehen, dass wir uns für dieses Beispielprogramm einer sehr abstrakten Schnittstelle bedient haben, denn es ist beispielsweise nicht möglich, mit dem Python-Script zu interagieren. Das Python-Script läuft bislang völlig autonom, und es können keine Werte zwischen ihm und dem C-Programm ausgetauscht werden. Aber gerade die Interaktion mit dem Hauptprogramm macht die Qualität einer eingebetteten Scriptsprache aus.


Galileo Computing - Zum Seitenanfang

26.3.2 Ein komplexeres Beispiel  Zur nächsten ÜberschriftZur vorigen Überschrift

Sie haben sicherlich erkannt, dass das vorangegangene Beispielprogramm noch nicht der Stein der Weisen war. In diesem Abschnitt soll ein besseres, komplexeres Programm entwickelt werden, das dazu in der Lage ist, Funktionen eines Python-Scripts direkt aufzurufen und Werte über die Funktionsschnittstelle zu schicken bzw. entgegenzunehmen. Außerdem soll das C-Programm dazu in der Lage sein, eigene Funktionen zu definieren, die aus dem Python-Script heraus aufgerufen werden können. Sie werden feststellen, dass auch dies dem Schreiben von Erweiterungen stark ähnelt.

Das folgende C-Programm soll ein Python-Script laden, das eine Funktion entscheide implementiert. Diese Funktion soll sich für einen von zwei übergebenen Strings entscheiden. Die Funktion könnte beispielsweise deshalb in ein Python-Script ausgelagert worden sein, weil man es dem Anwender ermöglichen will, die Funktion selbst zu implementieren und das Programm somit an die eigenen Bedürfnisse anzupassen.

Der Quellcode des Beispielprogramms sieht folgendermaßen aus:

#include <Python.h>
int main(int argc, char *argv[]) { char *ergebnis; PyObject *modul, *funk, *prm, *ret;
Py_Initialize(); PySys_SetPath("."); modul = PyImport_ImportModule("script");
if(modul) { funk = PyObject_GetAttrString(modul, "entscheide"); prm = Py_BuildValue("(ss)", "Hallo", "Welt"); ret = PyObject_CallObject(funk, prm);
ergebnis = PyString_AsString(ret); printf("Das Script hat sich fuer '%s' entschieden\n", ergebnis);
Py_DECREF(prm); Py_DECREF(ret); Py_DECREF(funk); Py_DECREF(modul); } else printf("Fehler: Modul nicht gefunden\n"); Py_Finalize(); }

In der Hauptfunktion main des C-Programms wird zunächst der Python-Interpreter durch Aufruf von Py_Initialize initialisiert. Danach wird durch die Funktion PySys_SetPath das lokale Programmverzeichnis als einziger Ordner festgelegt, aus dem Module importiert werden können. Beachten Sie, dass dieser Funktionsaufruf sowohl dem C- als auch dem Python-Programm verbietet, globale Module wie beispielsweise math einzubinden. Wenn Sie solche Module benötigen, dürfen Sie die Import-Pfade nicht, wie es in diesem Beispiel geschehen ist, überschreiben, sondern Sie sollten sich den Pfad mit Py_GetPath holen, ihn um das Verzeichnis . erweitern und mit PySys_SetPath setzen. Beachten Sie, dass das lokale Programmverzeichnis standardmäßig nicht als import-Pfad eingetragen ist.

Durch Aufruf der Funktion PyImport_ImportModule wird ein Modul eingebunden und als PyObject-Pointer zurückgegeben. Beachten Sie, dass, wenn die entsprechenden Pfade festgelegt wurden, sowohl lokale als auch globale Module mit dieser Funktion eingebunden werden können. Nachfolgend prüfen wir, ob das Modul erfolgreich geladen wurde. Bei einem Misserfolg gibt die Funktion PyImport_ImportModule wie die meisten anderen Funktionen, die einen PyObject-Pointer zurückgeben, NULL zurück. Beachten Sie, dass es immer ratsam ist, die zurückgegebenen PyObject-Pointer auf NULL zu testen. Im Beispielprogramm wurde dies nur exemplarisch bei modul gemacht.

Nachfolgend wird durch Aufruf der Funktion PyObject_GetAttrString ein Pointer auf die Funktion entscheide des Moduls script erstellt. Um die Funktion aufrufen zu können, müssen die Funktionsparameter in Form eines Tupels übergeben werden. Dazu erzeugen wir mittels Py_BuildValue ein neues Tupel, das die beiden Strings "Hallo" und "Welt" enthält, von denen die Funktion entscheide einen auswählen soll.

Durch Aufruf der Funktion PyObject_CallObject wird die Funktion funk schlussendlich aufgerufen und ihr Rückgabewert ebenfalls in Form eines Pointers auf PyObject zurückgegeben. Da es sich bei dem Rückgabewert um einen String handelt, können wir diesen mittels PyString_AsString zu einem C-String konvertieren und dann mit printf ausgeben.

Die in diesem Beispiel aufgerufene Python-Funktion entscheide sieht folgendermaßen aus und befindet sich in der Programmdatei script.py:

def entscheide(a, b): 
    return (a if min(a) < min(b) else b)

Die Funktion bekommt zwei Strings a und b übergeben und gibt einen der beiden zurück. Die Entscheidung, welcher der beiden Strings zurückgegeben wird, hängt davon ab, in welchem der alphabetisch kleinste Buchstabe enthalten ist.

Im nächsten Beispielprogramm soll es dem Python-Script ermöglicht werden, bestimmte Funktionen des C-Programms aufzurufen. Es soll dem Script also gewissermaßen eine API zur Verfügung gestellt werden, die es verwenden kann. Diese Idee liegt nicht nur gedanklich sehr nah an den in Abschnitt 26.2 besprochenen Extensions, sondern wird auch ganz ähnlich umgesetzt. Der Quelltext des Beispielprogramms sieht folgendermaßen aus:

#include <Python.h>
static PyObject *testfunktion(PyObject *self, PyObject *args) { int a, b; if(!PyArg_ParseTuple(args, "ii", &a, &b)) return NULL; return Py_BuildValue("i", a + b); }
static PyMethodDef MethodTable[] = { {"testfunktion", testfunktion, METH_VARARGS, "Testfunktion"}, {NULL, NULL, 0, NULL} };
int main(int argc, char *argv[]) { FILE *f;
Py_Initialize(); PySys_SetPath("."); Py_InitModule("api", MethodTable);
f = fopen("script.py", "r"); PyRun_SimpleFile(f, "script.py"); fclose(f);
Py_Finalize(); }

Zunächst wird die Funktion testfunktion definiert, die später dem Python-Script zur Verfügung gestellt werden soll. Im Beispiel berechnet die Funktion schlicht die Summe zweier ganzer Zahlen, die ihr als Parameter übergeben werden. Danach wird eine MethodeTable erstellt, ganz als würden wir eine Erweiterung schreiben. Und wie bei einer Erweiterung auch, wird die Funktion test funktion dem Python-Script später über ein Modul zur Verfügung stehen.

Dieses Modul, im Beispiel api genannt, wird durch den Aufruf der Funktion Py_InitModule eingerichtet. Schlussendlich brauchen wir nur noch die Funktion PyRun_SimpleFile aufzurufen, um das Python-Script script.py zu interpretieren. Der Funktion PyRun_SimpleFile muss dabei ein geöffnetes Dateiobjekt übergeben werden.

Das Python-Script, das von diesem C-Programm aufgerufen wird, könnte beispielsweise folgendermaßen aussehen:

import api 
print "Zwei plus zwei ist:", api.testfunktion(2, 2)

Galileo Computing - Zum Seitenanfang

26.3.3 Python-API-Referenz  topZur vorigen Überschrift

Nachdem die Python API in den Themenbereichen »Erweitern und Einbetten von Python« bereits verwendet wurde, soll an dieser Stelle eine kleine Referenz dieser API stehen. Beachten Sie dabei, dass die Python API sehr umfangreich ist und in diesem Abschnitt keinesfalls vollständig behandelt werden kann. Aus diesem Grund beschränken wir uns auf die Beschreibung der Funktionen der Python API, die in den Beispielprogrammen der vorherigen Abschnitte vorgekommen sind.

Die Funktionen sind in alphabetischer Reihenfolge aufgeführt.

PyObject *Py_BuildValue(const char *format, …)

Erzeugt eine Instanz eines Python-Datentyps mit einem bestimmten Wert. Der String format spezifiziert dabei den Datentyp. Die folgende Tabelle listet die wichtigsten Werte für format mit ihrer jeweiligen Bedeutung auf.


Tabelle 26.3  Mögliche Angaben im Formatstring
Formatstring Beschreibung
"s"

Erzeugt eine Instanz des Python-Datentyps str aus einem C-String (char *).

"u"

Erzeugt eine Instanz des Python-Datentyps unicode aus einem C-Buffer mit Unicode-Daten (Py_UNICODE *).

"i"

Erzeugt eine Instanz des Python-Datentyps int aus einem C-Integer (int).

"c"

Erzeugt eine Instanz des Python-Datentyps str aus einem C-Zeichen (char). Der resultierende String hat die Länge 1.

"d"

Erzeugt eine Instanz des Python-Datentyps float aus einer C-Gleitkommazahl (double). Analog dazu existiert "d" für den C-Datentyp float.

"(…)"

Erzeugt eine Instanz des Python-Datentyps tuple. Anstelle der Auslassungszeichen müssen die Datentypen der Elemente des Tupels angegeben werden. "(iii)" würde beispielsweise ein Tupel mit drei ganzzahligen Elementen erzeugen.

"[…]"

Erzeugt eine Instanz des Python-Datentyps list.

"{…}"

Erzeugt eine Instanz des Python-Datentyps dict.


Beachten Sie, dass ein C-String, der an die Funktion Py_BuildValue übergeben wird, um einen Python-String zu erzeugen, stets kopiert wird. Das bedeutet insbesondere, dass Sie jeden dynamisch allokierten String wieder freigeben müssen, selbst wenn er an die Funktion Py_BuiltValue übergeben wurde.

void Py_Finalize()

Die Funktion Py_Finalize deinitialisiert den Python-Interpreter und gibt den vom Interpreter belegten Speicher frei. Diese Funktion sollte beim Embedding des Python-Interpreters aufgerufen werden, wenn der Interpreter nicht mehr benötigt wird.

void Py_INCREF(PyObject *o), void Py_DECREF(PyObject *o)

Die Makros Py_INCREF und Py_DECREF erhöhen (inkrementieren) bzw. verringern (dekrementieren) den Reference Count der Instanz o um 1.

void Py_Initialize()

Die Funktion Py_Initialize initialisiert den Python-Interpreter und sollte aufgerufen werden, bevor der Interpreter beim Embedding eingesetzt wird.

PyObject *Py_InitModule(char *name, PyMethodDef *methods))

Erzeugt ein Python-Modul mit dem Namen name. Das Modul enthält den Inhalt, der von der Method Table methods vorgeschrieben wird. Das erstellte Modul wird in Form einers PyObject-Pointers zurückgegeben.

Beachten Sie, dass es sich bei dem zurückgegebenen Pointer um eine geliehene Referenz handelt, dass Sie also den Referenzzähler nicht dekrementieren müssen.

void Py_XINCREF(PyObject *o), void Py_XDECREF(PyObject *o)

Die Makros Py_XINCREF und Py_XDECREF erhöhen bzw. verringern den Reference Count der Instanz o um 1. Dabei prüfen die Makros vorher, ob für o NULL übergeben wurde.

int PyArg_ParseTuple(PyObject *args, const char *format, …)

Die Funktion PyArg_ParseTuple liest die einer Funktion übergebenen Argumente aus und speichert sie in lokale Variablen. Als erster Parameter muss ein Tupel übergeben werden, das die Parameter enthält. Ein solches Tupel bekommt jede Python-Funktion in C übergeben. Beachten Sie, dass mit PyArg_ParseTuple nur Positionsargumente ausgelesen werden können.

Der zweite Parameter format ist ein String, ähnlich dem Formatstring von Py_BuildValue und legt fest, wie viele Parameter ausgelesen werden sollen und welche Datentypen diese haben. Zum Schluss akzeptiert die Funktion PyArg_Parse Tuple beliebig viele Pointer auf Variablen, die mit den ausgelesenen Werten gefüllt werden sollen.

Im Erfolgsfall gibt die Funktion True zurück. Bei einem Fehler wirft die Funktion eine entsprechende Exception und gibt False zurück.

void PyErr_SetString(PyObject *type, PyObject *value)

Die Funktion PyErr_SetString wirft eine Python-Exception. Sie bekommt den Typ der auszulösenden Exception als ersten Parameter übergeben. Das kann eine der vordefinierten Standardexceptions, beispielsweise PyExc_NameError oder PyExc_ValueError, sein. Als zweiter Parameter wird der Wert der Exception übergeben, üblicherweise ein String, der eine Fehlermeldung enthält.

Beachten Sie, dass Sie den Reference Count einer Standardexception nicht erhöhen müssen, wenn Sie sie an PyErr_SetString übergeben.

PyObject *PyImport_ImportModule(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)

Diese C-Funktion lädt ein Python-Modul und ist äquivalent zu einem Aufruf der Built-in Function __import__ aus Python heraus. Im einfachsten Fall braucht nur der Parameter name übergeben werden, der den Namen des zu ladenden Moduls enthält.

Beachten Sie, dass Sie das lokale Programmverzeichnis zuerst mittels PySys_Set Path einrichten müssen, bevor lokale Module eingebunden werden können.

void PyMem_Free(void *p)

Die Funktion PyMem_Free gibt den allokierten Speicherblock frei, auf den p zeigt.

void *PyMem_Malloc(size_t n)

Die Funktion PyMem_Malloc allokiert einen Speicherbereich der Größe n und gibt einen Pointer auf den allokierten Speicher zurück.

PyObject *PyObject_CallObject(PyObject *callable_object, PyObject *args)

Die Funktion PyObject_CallObject ruft das aufrufbare Objekt callable_objekt, beispielsweise also ein Funktions- oder Methodenobjekt, auf und übergibt dabei die Parameter args. Wenn keine Parameter übergeben werden sollen, kann für args NULL übergeben werden.

Das Ergebnis des Objektaufrufs wird als Rückgabewert zurückgegeben. Bei einem Fehler wird NULL zurückgegeben.

PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)

Gibt eine Referenz auf das Attribut mit dem Namen attr_name der Instanz o zurück. Im Fehlerfall wird NULL zurückgegeben.

int PyRun_SimpleFile(FILE *fp, const char *filename)

Die Funktion PyRun_SimpleFile führt eine Python-Programmdatei aus. Dabei wird der Inhalt der Programmdatei in Form eines geöffneten Datei-Pointers übergeben. Zusätzlich sollte der Dateiname der Programmdatei als zweiter Parameter übergeben werden.

Die Funktion gibt 0 zurück, wenn der Code erfolgreich ausgeführt wurde, und –1, wenn ein Fehler aufgetreten ist.

int PyRun_SimpleString(const char *command)

Die Funktion PyRun_SimpleString verhält sich ähnlich wie PyRun_SimpleFile mit dem Unterschied, dass der auszuführende Python-Code aus dem String command statt aus einer Datei gelesen wird.

char *PyString_AsString(PyObject *string)

Gibt den internen C-Buffer des Python-Strings string zurück. Beachten Sie, dass Sie nur dann in den zurückgegebenen Buffer schreiben dürfen, wenn Sie ihn zuvor beispielsweise mit der Funktion PyString_FromStringAndSize selbst erstellt haben.

PyObject *PyString_FromStringAndSize(const char *v, Py_ssize_t len)

Erzeugt eine Instanz des Python-Datentyps str mit der Länge len und dem Inhalt des C-Strings v. Für v kann NULL übergeben werden. Die Funktion gibt eine Referenz auf die erzeugte Instanz zurück.

void PySys_SetPath(char *path)

Über die Funktion PySys_SetPath können die Verzeichnisse festgelegt werden, in denen nach Modulen gesucht wird. Die Funktion entspricht damit dem Schreiben des Strings sys.path in Python. Umgekehrt können die gesetzten Verzeichnisse über die Funktion PySys_GetPath ausgelesen werden.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






 <<   zurück
  
  Zum Katalog
Zum Katalog: Python






Python
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Linux






 Linux


Zum Katalog: Ubuntu GNU/Linux






 Ubuntu GNU/Linux


Zum Katalog: Praxisbuch Web 2.0






 Praxisbuch Web 2.0


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Praxisbuch Objektorientierung






 Praxisbuch Objektorientierung


Zum Katalog: Einstieg in SQL






 Einstieg in SQL


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo