CPython: PDF Handout - Berthold Höllmann: Vorträge bei der

Werbung
Werkzeuge zur Erweiterung von CPython
Authors:
Date:
Version:
Berthold Höllmann
2009-09-06 13:33:01 +0200 (So, 06 Sep 2009)
23
Inhalt
1 Einleitung
2
2 Libraries/Utilities: Einbinden vorhandener Bibliotheken
2
3 Libraries/Utilities: Entwicklung eigenes Codes
3
4 ctypes
3
5 ctypes: Beispiel
3
6 numpy/f2py
3
7 numpy/f2py: Beispiel
4
8 numpy/f2py: Beispiel (2)
4
9 SWIG
4
10 SWIG: Beispiel
4
11 SWIG: Beispiel (2)
5
12 SWIG: Beispiel (3)
5
13 SWIG: Beispiel (4)
5
14 sip
6
15 sip: Beispiel
6
16 sip: Beispiel (2)
7
17 sip: Beispiel (3)
7
18 sip: Beispiel (4)
7
19 Handgeschriebene Erweiterungen
7
20 Handgeschriebene Erweiterungen: Beispiel
8
1
21 Handgeschriebene Erweiterungen: Beispiel
8
22 CXX
8
23 CXX: Beispiel
8
24 CXX: Beispiel (2)
9
25 pyrex
9
26 pyrex: Beispiel
9
27 pyrex: Beispiel (2)
10
28 pyrex: Beispiel (3)
10
29 weave
10
30 weave: Beispiel
10
31 Boost.Python
11
32 Boost.Python: Beispiel
11
33 Boost.Python: Beispiel (2)
11
34 distutils
11
35 Diskussion
12
1
Einleitung
Oft ist es aus verschieden Gründen nötig oder wünschenswert, Code aus anderen Programmiersprachen in CPython einzubinden. Oft ist dieser Code in C oder C++ geschrieben, bei wissenschaftlichen
Anwendungen in FORTRAN. Die Gründe können u.a. sein
• Beschleunigung von Anwendungen mit eigenem Code,
• Beschleunigung von Anwendungen mit fremdem Code,
• Zugriff auf spezielle Bibliotheken.
2
Libraries/Utilities: Einbinden vorhandener Bibliotheken
Natürlich immer auch zum Entwickeln eigener Bibliotheken.
• ctypes1 (Shared Libraries, Standard CPython Library seit 2.5)
• numpy/f2py2 (FORTRAN/C)
• SWIG3 (C/C++)
• sip4 (C++) (Entwickelt für PyQt)
• Handgeschriebene Erweiterung (Python/C API Reference Manual5, Extending and Embedding
the Python Interpreter6) (C) ( aktuelles“ Beispiel: pysqlite7)
”
2
3
Libraries/Utilities: Entwicklung eigenes Codes
Natürlich immer auch zum Einbinden von vorhandenem Code.
8
• CXX (C++)
• pyrex9 (C) (Oder zum Wrappen vorhandenen Codes: pytables10)
• weave11 (C/C++) (Einbetten von C Code in Python Code, Bestandteil von SciPy12)
• Boost.Python13 (C++)
4
ctypes
• Einbinden von dynamischen Bibliotheken.
• Kein Compiler benötigt, Einbindung aus Python heraus
• PyOpenGL wird auf ctypes umgestellt
5
ctypes: Beispiel
>>> from ctypes import *
>>> cdll.LoadLibrary("libc.so.6") #doctest: +ELLIPSIS
<CDLL ’libc.so.6’, handle ... at ...>
>>> libc = CDLL("libc.so.6")
>>> libc.printf
#doctest: +ELLIPSIS
<_FuncPtr object at 0x...>
>>> print libc.time(None)
#doctest: +SKIP
1179046382
>>> res = libc.printf(
...
"dies %d ist %s ein %f Test\n",
...
3, "kleiner", c_double(4.5))
dies 3 ist kleiner ein 4.500000 Test
6
numpy/f2py
• Einbinden von FORTRAN und (auch) C Code
12
• Wird in SciPy
benutzt um BLAS und Lapack Code einzubinden
• Ggf. wird FORTRAN Compiler benötigt
• Code Generator
• Eingebautes Build System
• Arbeitet Wahlweise direkt mit dem, durch spezielle Kommentare angereicherten, Quellcode oder
einer Datei zur Beschreibung des Interfaces (.pyf).
3
7
numpy/f2py: Beispiel
tst.f :
SUBROUTINE addit(out, in_a, in_b)
REAL*8 out
INTEGER in_a
REAL*8 in_b
Cf2py intent(out) out
Cf2py intent(in) in_a
Cf2py intent(in) in_b
out = in_a + in_b
RETURN
END
8
numpy/f2py: Beispiel (2)
> f2py -c addit.f -m addit
>>> import addit
>>> print dir(addit)
[’__doc__’, ’__file__’, ’__name__’, ’__package__’, ’__version__’, ’addit’]
>>> print addit.addit.__doc__ #doctest: +NORMALIZE_WHITESPACE
addit - Function signature:
out = addit(in_a,in_b)
Required arguments:
in_a : input int
in_b : input float
Return objects:
out : float
<BLANKLINE>
>>> addit.addit(2, 3.)
5.0
9
SWIG
• Unterstützt eine Auswahl an verschiedenen Ziel (aufrufenden) Sprachen (von der SWIG3 Website):
Python, Tcl, Perl, Guile, Java, Ruby, Mzscheme, PHP, Objective Caml (Ocaml), Pike, C#, the
Chicken scheme compiler, Allegro CL, Modula-3, Lua, CLISP, Common Lisp with UFFI, Common
Lisp with CFFI, und R
• Code Generator
• Benutzt von PyOpenGL2
• Interface ändert sich häufig und zwischen patch releases. (PyOpenGL2 2.0.1 festgelegt auf Version
1.3.13, 2.0.2 auf 1.3.23)
10
SWIG: Beispiel
Aus Tutorial von Website (SWIG3)
swig example.c:
4
#include <time.h>
double My_variable = 3.0;
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
int my_mod(int x, int y) { return (x%y); }
char *get_time()
{
time_t ltime; time(&ltime);
return ctime(&ltime);
}
11
SWIG: Beispiel (2)
swig example.i:
/* example.i */
%module swig_example
%{
/* Put header files here or function declarations like below */
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}
extern
extern
extern
extern
12
double My_variable;
int fact(int n);
int my_mod(int x, int y);
char *get_time();
SWIG: Beispiel (3)
> swig -python swig_example.i
> gcc -c swig_example.c swig_example_wrap.c \
-I/usr/local/include/python2.5
> ld -shared swig_example.o swig_example_wrap.o \
-o _swig_example.so
> ls *swig_example*
_swig_example.so*
swig_example.i swig_example.py
swig_example_wrap.o swig_example.c swig_example.o
swig_example_wrap.c
13
SWIG: Beispiel (4)
>>> import swig_example
>>> swig_example.fact(5)
120
>>> swig_example.my_mod(7,3)
1
5
>>> swig_example.get_time()
’Sun May 13 14:33:41 2007\n’
14
#doctest: +SKIP
sip
• Einbinden von C++ Klassen in Python
• Code Generator
• Entwickelt für PyQt und PyKDE
15
sip: Beispiel
sip example.h:
// Define the interface to the word library.
#include <string>
class Word {
const std::string the_word;
public:
Word(const char *w);
char *reverse() const;
};
sip_example.cpp im Handout
sip example.cpp:
// Define the word library.
#include <cstring>
#include <cstdlib>
#include <iostream>
#include "sip_example.h"
Word::Word(const char *w) : the_word(w) {
};
char *Word::reverse() const {
size_t wlen, i;
char *res;
wlen = the_word.length();
res = (char*)calloc(wlen+1, sizeof(char));
for (i=0; i<wlen; i++) {
res[wlen-i-1] = the_word[i];
}
return res;
};
6
16
sip: Beispiel (2)
sip example.sip:
// Define the SIP wrapper to the word library.
%Module sip_example 0
class Word {
%TypeHeaderCode
#include "sip_example.h"
%End
public:
Word(const char *w);
char *reverse() const;
};
17
sip: Beispiel (3)
> g++
-c -o sip_example.o sip_example.cpp
> sip -c . sip_example.sip
> g++ -c -I/usr/local/include/python2.5 \
sipsip_examplecmodule.cpp
> g++ -c -I/usr/local/include/python2.5 \
sipsip_exampleWord.cpp
> g++ -shared sip_example.o \
sipsip_examplecmodule.o \
sipsip_exampleWord.o \
-o sip_example.so
> ls *sip_e*
sipAPIsip_example.h
sip_example.cpp
sip_example.h
sip_example.sip
18
sip_example.so*
sipsip_exampleWord.cpp
sipsip_exampleWord.h
sipsip_exampleWord.o
sipsip_examplecmodule.cpp
sipsip_examplecmodule.o
sip: Beispiel (4)
>>> import sip_example
>>> w = sip_example.Word(
...
"Dies ist ein Test"[::-1])
>>> print w
#doctest: +ELLIPSIS
<sip_example.Word object at 0x...>
>>> print dir(w)
#doctest: +ELLIPSIS
[... ’reverse’]
>>> w.reverse()
’Dies ist ein Test’
19
Handgeschriebene Erweiterungen
• Funktioniert mit jedem CPython port
7
• Entwickler verantwortlich für Reference counting, korrekte Übergabeparameter, Aufbau der Rückgabeparameter.
• Code in C
• Wird von allen Code Generatoren und Einbindungs Bibliotheken verwendet.
20
Handgeschriebene Erweiterungen: Beispiel
manual example.c: (aus Python Docs)
#include "Python.h"
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command; int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return Py_BuildValue("i", sts); }
static PyMethodDef ManualMethods[] = {
{"system", spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL, NULL, 0, NULL}};
PyMODINIT_FUNC initmanual_example(void) {
PyObject *m;
m = Py_InitModule("manual_example", ManualMethods);}
21
Handgeschriebene Erweiterungen: Beispiel
>>> import manual_example
>>> status = manual_example.system("ls -l")
22
CXX
• C++ Klassen zur Einbindung von C++ Code in Python.
• Definiert z.B. C++ Klassen für Python Standard Typen.
• Bietet Numeric Interface (NumPy)
• C++ Ausnahmen werden zu Python Exceptions
• Mit Standard distutils zu übersetzen, benötigt jedoch zusätzlich Quelldateien für Hilfsfunktionen.
23
CXX: Beispiel
cxx example.cxx:
class example_module : public ExtensionModule<example_module> {
public:
8
example_module()
: ExtensionModule<example_module>( "cxx_example" ) {
add_varargs_method("sum", &example_module::ex_sum,
"sum(arglist) = sum of arguments");
add_varargs_method("test", &example_module::ex_test,
"test(arglist) runs a test suite");
initialize("documentation for the example module" ); }
virtual ~example_module() {}
private:
Object ex_sum(const Tuple &a);
Object ex_test(const Tuple &a);};
extern "C" void initcxx_example() {
static example_module* example = new example_module; }
24
CXX: Beispiel (2)
>>> import cxx_example
>>> dir(cxx_example)
[’__doc__’, ’__file__’, ’__name__’, ’__package__’, ’sum’, ’test’]
>>> cxx_example.test()
Module test ok.
>>> print cxx_example.sum(1, 2, 3)
6.0
>>> print cxx_example.sum(*range(10))
45.0
25
pyrex
• Python ähnliche Sprache zum Erstellen von Python Erweiterungen
• Zum Einbinden von C Code werden die .h Dateien in Pyrex neu geschrieben.
• Vermittelt die Unterschiede im C und Python Typen System.
26
pyrex: Beispiel
pyrex example.pyx:
def primes(int kmax):
cdef int n, k, i
cdef int p[1000]
result = []
if kmax > 1000:
kmax = 1000
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] <> 0:
i = i + 1
if i == k:
p[k] = n
9
k = k + 1
result.append(n)
n = n + 1
return result
27
pyrex: Beispiel (2)
pyrex example.pyx:
cdef class Spam:
cdef int amount
def __new__(self):
self.amount = 0
def get_amount(self):
return self.amount
def set_amount(self, new_amount):
self.amount = new_amount
def describe(self):
print self.amount, "tons of spam!"
28
pyrex: Beispiel (3)
>>> import pyrex_example
>>> dir(pyrex_example)
#doctest: +ELLIPSIS
[’Spam’, ..., ’primes’]
>>> pyrex_example.primes(4)
[2, 3, 5, 7]
>>> s = pyrex_example.Spam()
>>> s.set_amount(33)
>>> s.describe()
33 tons of spam!
29
weave
• Übersetzen von Ausdrücken oder inline Code
• Ergebnisse der Übersetzung werden gecached
• Unterstützung für numpy arrays
30
weave: Beispiel
>>> from scipy import weave
>>> code = r"""
... int i;
10
... py::tuple results(2);
... for (i=0; i<a.length(); i++) {
...
a[i] = i;
... }
... results[0] = 3.0;
... results[1] = 4.0;
... return_val = results;
... """
>>> a = [None]*10
>>> print weave.inline(code, [’a’])
(3.0, 4.0)
31
Boost.Python
• Nahtlose Integration von C++ und Python
• boost: C++ Bibliothek von Template Fans
• Wrapper generatoren unter C++/Python interfacing14
32
Boost.Python: Beispiel
boost example.cpp:
#include <boost/python.hpp>
using namespace boost::python;
struct World {
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
BOOST_PYTHON_MODULE(boost_example) {
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set);
}
33
Boost.Python: Beispiel (2)
>> import boost_example
>> dir(boost_example)
[’World’, ’__doc__’, ’__file__’, ’__name__’]
>> planet = boost_example.World()
>> planet.set(’howdy’)
>> planet.greet()
’howdy’
34
distutils
2
numpy/f2py -- Unterstützt von numpy.distutils
SWIG3 -- Unterstützt von distutils
sip4 -- Eigene Distutils Erweiterung (sipdistutils)
11
8
CXX -- Standard distutils, allerdings müssen Support Dateien gesucht werden.
9
pyrex -- Eigene Distutils Erweiterung (Pyrex.Distutils)
13
Boost.Python -- Ersteller bevorzugen bjam. Standard distutils möglich, allerdings müssen
Header Dateien und Bibliotheken gesucht werden.
Links
35
Diskussion
Fragen / Anmerkungen?
Hamburger Python User Group • 2007/05/16
View document source. Generated on: 2009-09-28 13:14 UTC. Generated by Docutils from reStructuredText
source.
1
http://docs.python.org/lib/module-ctypes.html
2
http://cens.ioc.ee/projects/f2py2e/
3
http://swig.sourceforge.net/
4
http://www.riverbankcomputing.co.uk/sip/index.php
5
http://docs.python.org/api/api.html
6
http://docs.python.org/ext/ext.html
7
http://www.pysqlite.org
8
http://cxx.sourceforge.net/
9
http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
10
http://www.pytables.org/
11
http://scipy.org/Weave
12
http://scipy.org/
13
http://boost.org/libs/python/doc/index.html
14
http://www.language-binding.net/
12
Herunterladen