Home
Python ... Python software ... ... License ... Introduction ... German texts ... ... Einführung ... ... Workshop Python ... ... Perl und Python
Chemical Engineering ... Links
About me ... Publications/Talks |
Perl und Python - Zwei Skriptsprachen im Vergleich
Stefan Schwarzer
13. Mai 2000
Zweite Braunschweiger Linux-Tage
Überblick
Was sind Skriptsprachen?
Es gibt anscheinend keine einheitliche Definition von
"Skriptsprache." Üblicherweise werden aber folgende
Eigenschaften angenommen:
- Die Sprache wird nicht - explizit - kompiliert oder
mit Bibliotheken verbunden. Dies geschieht hinter den
Kulissen; ein veränderter Quelltext ändert sein Verhalten
bei der nächsten Ausführung.
- Typdeklarationen für Variablen sind freiwillig und/oder
gar nicht möglich.
- "Höhere" Skriptsprachen, darunter Perl und Python, bieten
komplexe Datenstrukturen (Listen, assoziative Listen) und
dazu gehörige Operationen.
Ursprünge
Perl
Perl (Practical extraction and report language) wurde von
Larry Wall entwickelt, um - wie der Name der Sprache verrät -
Zusammenfassungen von Programmausgaben zu erzeugen. Wall orientierte
sich vor allem an Shell-Skriptsprachen und C.
Die Einstiegsseite für Perl ist http://www.perl.com/.
Python
Python (benannt nach "Monty Python") geht auf Guido van
Rossum zurück, der damit eine leicht zu lernende, gut lesbare
und leistungsfähige Sprache schaffen wollte. Einige
Spracheigenschaften stammen von ABC.
Die erste Anlaufstelle für Python ist
http://www.python.org/.
Datentypen
Perl
Perl kennt drei Gruppen von Datentypen, die durch unterschiedliche
Präfixe gekennzeichnet werden:
- Skalare, z. B.
$zahl. Skalare nehmen Zahlen
(number), Zeichenketten (string) oder Zeiger (reference) auf. Die
Interpretation einer Variable kann durch die darauf
angewendeten Operatoren beeinflusst werden.
$a = 17; $b = 2; print $a > $b;
ergibt 1 (wahr),
$a = 17; $b = 2; print $a gt $b;
ergibt '' (falsch), weil $a und $b
zum Vergleich in die Zeichenketten '17' und
'2' gewandelt werden.
- Listen (array), z. B.
@liste. Listen enthalten Skalare
in einer "festen" Reihenfolge, die nur durch das Programm
verändert werden kann.
@liste = (1, 3); push @liste, 7; print $liste[2];
gibt 7 aus. (Das erste Element der Liste hat den Index
Null.)
- Assoziative Listen (hash), z. B.
%hash. Hashes
speichern Werte (values), auf die über Schlüssel (keys)
zugegriffen wird.
%hash = (b => 'Perl', a => 5); print $hash{a};
gibt den Wert 5 aus, der zum Schlüssel
a gehört.
Python
Auch in Python gibt es die drei Gruppen von Datentypen, wie sie in
Perl vorkommen. Jedoch sind sie nicht besonders markiert und sind
weiter unterteilt:
- Skalare haben als Untertypen Ganzzahl (integer), Ganzzahl
mit beliebig vielen Stellen (long integer), Fließkommazahlen
(float), komplexe Zahlen (complex) und Zeichenketten (string).
i = 1; li = 9999999999L; f = 3.14; c = 3+4j; s = 'Hello'
Es gibt keinen expliziten Zeigertyp.
- Sequenzen (sequence) nehmen eine feste Folge anderer Objekte
auf. Das können bspw. auch weitere Sequenzen sein. Sequenzen
werden weiter unterteilt in Listen (list) und Tupel (tuple).
L = [1, 3]; L.append(7); print L[2]
gibt 7 aus, vgl. das Listenbeispiel bei Perl, während
T = (1, 3); T.append(7)
eine Fehlermeldung erzeugt. Tupel können, wenn einmal erzeugt,
nicht mehr - ohne Neuzuweisung - verändert werden.
- Assoziative Listen (dictionaries) entsprechen den
Hashes in Perl:
D = {'b': 'Python', 'a': 5}; print D['a']
gibt, analog zum Perl-Beispiel, 5 aus.
Operatoren
Perl
Perl besitzt sehr viele Operatoren, die zum großen Teil aus
Shell-Sprachen und von C übernommen sind. Einige Operatoren sind
"doppelt", damit sie sowohl für Zahlen als auch für Zeichenketten
wie erwartet funktionieren. Perls Operatoren sind
() [] {} <> -> ++ -- ** ! ~ \ =~ !~ * / % x + - . << >>
-r -w -x -o -R -W -X -O -e -z -s -f -d -l -p -S -b -c -t
-u -g -k -M -A -C
< > <= >= lt gt le ge == != <=> eq ne cmp
& | ^ && || .. ?:
= **= += -= .= *= /= \%= x= &= |= ^= <<= >>= &&= ||=
, => not and or xor
Python
- Python besitzt deutlich weniger Operatoren, nämlich
() [] {} `` [:] . + - ~ ** * / % << >> & ^ |
is in < <= > >= == <> != not and lambda or
Seit Python 2.0 gibt es analog zu Perl außerdem die Operatoren
+= -= **= *= /= %= <<= >>= &= ^= |=
- Andererseits muss man für viele der Aufgaben, die Perl mit seinen
eingebauten Operatoren abdeckt, eingebaute oder Funktionen aus Modulen
aufrufen, bspw.
$datei_da = -e 'dateiname'; # Dateiexistenz in Perl
datei_da = os.path.exists( 'dateiname' ) # dito in Python
Die am häufigsten benötigten Operatoren sind aber auch in Python
leicht zugänglich, z. B. arithmetische und
Vergleichsoperatoren.
Anweisungsfolgen
Perl
- In Perl können Anweisungen "frei" über mehrere Zeilen
verteilt werden. Zwischen Anweisungen stehen Semikola:
@liste = ( 1, 3 ); push # Kommentar: sinnloser Umbruch ;-)
@liste, 7; print $liste[ 2 ];
- Anweisungen der selben logischen Ebene werden in geschweifte
Klammern eingefasst:
if( $a > 0 )
{
$b = 1;
$c = 2;
}
Python
- In Python stehen Anweisungen, die zur selben logischen
Gruppe gehören, auf einzelnen Zeilen und gleichmäßig
eingerückt:
if a > 0:
b = 1
c = 2
- Es ist kein Zeichen (z. B. "}") nötig, um einen
Anweisungsblock abzuschließen. Verwendet man Semikola, kann
man, wie in den Beispielen weiter oben, auch mehrere Anweisungen
auf eine Zeile schreiben.
- Eine Anweisung wird fortgesetzt, wenn am Ende der
vorhergehenden Zeile ein Backslash
\ steht oder
noch Klammern "offen sind."
Bedingte Anweisungen
Perl
- Perl kennt eine
if-Anweisung, aber auch eine
unless-Anweisung. Letztere entspricht einer
if-Anweisung mit negierter Logik, bspw. ist
if( $a > $b )
{
$a = $b; # $a maximal so gross wie $b
}
dasselbe wie
unless( $a <= $b )
{
$a = $b;
}
- Der
if-Zweig kann mit elsif und
else ergänzt werden.
if( $a > $b )
{
print '$a ist groesser als $b.', "\n";
}
elsif( $a < $b )
{
print '$a ist kleiner als $b.', "\n";
}
else
{
print '$a ist gleich $b.', "\n";
}
- Soll eine einzelne Anweisung bedingt ausgeführt werden,
können
if oder unless nachgestellt
werden.
$n++ if( $a > $b );
Python
- Python kennt kein
unless und kein nachgestelltes
if.
- Das vorletzte Perl-Beispiel lässt sich folgendermaßen auf
Python übertragen:
if a > b:
print 'a ist groesser als b.'
elif a < b:
print 'a ist kleiner als b.'
else:
print 'a ist gleich b.'
- Python erlaubt "abgekürzte" Bereichsabfragen.
if 2 <= a <= 7: print 'a liegt im Intervall [2, 7].'
Schleifen
Perl
- In Perl gibt es
while-Schleifen. Der folgende Code
sammelt alle ganzen Zahlen von 0 bis 99 in einer Liste.
@liste = ();
$i = 0;
while( $i < 100 )
{
push @liste, $i;
$i++;
}
- Dasselbe kann man mit einer
for-Schleife erreichen.
@liste = ();
for $i (0 .. 99)
{
push @liste, $i;
}
- Noch viel kürzer geht es mit einer impliziten Schleife.
@liste = (0 .. 99);
- In Perl kann man eine Schleife mit
last
"vorzeitig" abbrechen.
$gefunden = 0;
for $eintrag ( @eintraege )
{
if( $gesucht eq $eintrag )
{
$gefunden = 1;
last; # Liste nicht weiter durchsuchen
}
}
Python
- In Python gibt es ebensolche Konstrukte. Die
while-Schleife lautet
liste = []
i = 0
while i < 100:
liste.append(i)
i = i + 1 # oder i += 1 seit Python 2.0
- Die
for-Schleife sieht so aus:
liste = []
for i in range(100):
liste.append(i)
- Auch die implizite Schleife hat eine Entsprechung.
liste = range(100)
range(100) erzeugt eine Liste aller ganzen Zahlen
von 0 bis 99, nicht bis 100.
- Python verwendet
break zum "vorzeitigen"
Verlassen von Schleifen.
gefunden = 0
for eintrag in eintraege:
if gesucht == eintrag:
gefunden = 1
break
Anwendungsbeispiel
Es soll eine Datei eingelesen, zeilenweise sortiert und in
eine Datei mit der zusätzlichen Endung '.sortiert'
geschrieben werden.
Perl
In Perl kann man das - in Anlehnung an "normale"
Programmiersprachen - so machen:
#!/usr/bin/perl -w
# Dateiname ermitteln
$dateiname = $ARGV[0]; # der Skriptname steht in $0
@zeilen = ();
# Datei lesen
open DATEI, "<$dateiname" or
die "$dateiname laesst sich nicht oeffnen\n";
while( !eof DATEI )
{
$zeile = <DATEI> or
die "$dateiname ist nicht lesbar\n";
push @zeilen, $zeile;
}
close DATEI;
# sortieren
@zeilen = sort @zeilen;
$dateiname = $dateiname . '.sortiert';
# Datei schreiben
open DATEI, ">$dateiname" or
die "$dateiname laesst sich nicht oeffnen\n";
for $zeile (@zeilen)
{
print DATEI $zeile or
die "$dateiname ist nicht schreibbar\n";
}
close DATEI or die "$dateiname ist nicht schreibbar\n";
Üblicher ist folgendes.
#!/usr/bin/perl -w
# Dateiname ermitteln
$dateiname = shift;
# Datei lesen
open DATEI, "<$dateiname" or
die "$dateiname laesst sich nicht oeffnen\n";
@zeilen = <DATEI> or
die "$dateiname ist nicht lesbar\n";
close DATEI;
# sortieren
@zeilen = sort @zeilen;
$dateiname .= '.sortiert';
# Datei schreiben
open DATEI, ">$dateiname" or
die "$dateiname laesst sich nicht oeffnen\n";
print DATEI @zeilen or
die "$dateiname ist nicht schreibbar\n";
close DATEI or die "$dateiname ist nicht schreibbar\n";
Python
In Python geht es ganz ähnlich.
#!/usr/bin/python
import sys
# Dateiname ermitteln
dateiname = sys.argv[1]
# Datei lesen
try:
datei = open(dateiname, 'r')
zeilen = datei.readlines()
datei.close()
except IOError:
print dateiname, "ist nicht lesbar"
sys.exit(1)
# Datei sortieren
zeilen.sort()
dateiname = dateiname + '.sortiert'
# Datei schreiben
try:
datei = open(dateiname, 'w')
datei.writelines(zeilen)
datei.close()
except IOError:
print dateiname, "ist nicht schreibbar"
Unterprogramme
Perl
- Unterprogramme werden in Perl mit dem Schlüsselwort
sub definiert.
- Der Funktionsrumpf wird in geschweifte Klammern
geschrieben.
- Argumente werden an die Funktion in der speziellen Liste
@_ übergeben; sie tragen keine Namen.
- Es können beliebige Perl-Datenstrukturen an den Aufrufer
zurückgegeben werden.
- Es kann ein Rückgabewert in der
return-Anweisung
angegeben werden, wenn nicht, ist der Rückgabewert der
zuletzt ausgewertete Ausdruck.
- Beim Aufruf eingebauter Funktionen können Klammern
weggelassen werden. (Unter bestimmten Bedingungen (Verwendung
von Prototypen) ist dies auch bei eigenen Funktionen
möglich.)
- Die folgende Funktion ermittelt den Index eines
Zahlenwertes in einer Liste.
sub index {
($gesucht, @eintraege) = @_;
my $i; # potenzieller Index
for $i (0 .. $#eintraege)
{
return $i if( $eintraege[$i] == $gesucht );
}
undef; # nicht gefunden
}
print index( 3, (1, 2, 3, 4) ); # suche 3 in der Liste
Python
- Unterprogramme werden in Python mit dem Schlüsselwort
def definiert.
- Der Funktionsrumpf wird eingerückt.
- Die Argumente werden als benannte Variablen übergeben.
- Es können beliebige Python-Datenstrukturen an den Aufrufer
zurückgegeben werden.
- Es kann ein Rückgabewert in der
return-Anweisung
angegeben werden, wenn nicht, ist der Rückgabewert der
besondere Wert None.
- Vorgabeargumente (wie in C++) sind erlaubt.
- Im Aufruf darf die Reihenfolge der Parameter verändert
werden, wenn sie entsprechend benannt werden.
- Diese Funktion entspricht der oben aufgeführten
Perl-Funktion:
def index(gesucht, eintraege):
for i in range( len(eintraege) ):
if eintraege[i] == gesucht:
return i
return None # nicht gefunden
print index( 3, [1, 2, 3, 4] ) # suche 3 in der Liste
print index( eintraege=[1, 2, 3, 4], # alternative
gesucht=3 ) # Formulierung
Module
Allgemeines
- Module sind Programmteile, die in eigene Dateien geschrieben
werden, um sie in mehreren Programmen verwenden zu können.
- Die Nutzbarkeit in mehreren Zusammenhängen muss beim Entwurf eines
Moduls bewusst berücksichtigt werden.
- Sowohl die Perl- als auch die Python-Distributionen enthalten
neben Interpreter und Dokumentation eine große Anzahl an Modulen,
bspw. zur Textverarbeitung und zur einfachen Verwendung von
Internet-Protokollen.
- Wenn es nicht ausdrücklich anders definiert wird, muss bei Verwendung
eines Befehls aus einem Modul im Hauptprogramm (oder einem
anderen Modul) dieser Befehl explizit genannt werden (s. Beispiele
unten).
Perl
Grundlagen
- Moduldateien tragen die Endung
pm (für "Perl
module").
- In Perl beginnt der Code einer Moduldatei mit der
package-Anweisung.
- Der zuletzt ausgewertete Ausdruck eines Moduls muss 1 (oder
allgemeiner: ein "wahrer" Wert) sein, um
dem Interpreter das erfolgreiche Laden des Moduls bekannt zu
machen.
- Zum Beispiel definiert das folgende Modul
EinModul
die Variablen $var1 und @var2 sowie eine
Funktion quadrat.
# EinModul.pm
# Definiere das Modul "EinModul"
package EinModul;
$var1 = 1;
@var2 = (2, 3);
sub quadrat
{
my $x = shift;
$x * $x;
}
1;
- In andere Dateien wird das Modul durch die
use-Anweisung geladen.
- Namen des geladenen Moduls werden mit dem Modulnamen, gefolgt
von zwei Doppelpunkten qualifiziert. Ein Symbol wie
$ oder @ geht dabei dem Modulnamen
voraus.
- Hier wird das im vorherigen Beispiel definierte Modul verwendet.
#!/usr/bin/perl
# Hauptprogramm
use EinModul;
$test = $EinModul::var1;
$test = EinModul::quadrat(7);
Exportieren von Namen
- Perl erlaubt sowohl dem Modul als auch dem importierenden Programm
eine Entscheidung, welche Namen im importierenden Programm ohne
Qualifizierung (also z. B.
$var1 statt
$EinModul::var1) verwendbar sein sollen.
- Auf der Modulebene kann das Exportieren nach folgendem
Muster gesteuert werden. (Es gibt noch mehr Möglichkeiten, die wir
hier nicht behandeln wollen.)
package EinModul;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw($var1);
@EXPORT_OK = qw($var1 @var2);
# weiterer Code ...
1;
Dabei gibt @EXPORT an, welche Namen standardmäßig
exportiert werden. @EXPORT_OK enthält die Namen, die
exportiert (bzw. importiert) werden dürfen.
- Auf der Ebene des importierenden Programms wird das Modul
so benutzt:
use EinModul; # importiere nur $var1
use EinModul qw(@var2); # importiere nur @var2
use EinModul qw($var1 quadrat); # Fehler
Die erste Form importiert die Namen, die in @EXPORT
angegeben wurden. Die zweite importiert nur die hier
genannten Namen (bzw. versucht es, siehe letzte Zeile).
Python
Grundlagen
- Moduldateien haben die Endung
.py, genau wie
"normale" Programme. Es ist so möglich, dieselbe
Datei als Modul oder als eigenständiges Programm zu verwenden.
- Es gibt keine besondere Anweisung, ein Modul als solches zu
kennzeichnen. Ein Modul unterscheidet sich von einem Programm
nur durch die Verwendung, nicht durch speziellen Code.
- Analog zum obigen Perl-Code ist das folgende Python-Modul.
#!/usr/bin/python
# EinModul.py
# Definiere das Modul EinModul
var1 = 1
var2 = [2, 3]
def quadrat(x):
return x * x
- In andere Dateien wird das Modul durch eine
import-Anweisung geladen.
- Namen des geladenen Moduls wird der Modulname, gefolgt von einem
Punkt, vorangestellt. Beispiel:
#!/usr/bin/python
# Hauptprogramm
import EinModul
test = EinModul.var1
test = EinModul.quadrat(7)
Exportieren von Namen
- Welche Namen eines Moduls in ein Programm importiert werden,
wird üblicherweise nur vom importierenden Programm gesteuert und
nicht vom Modul.
- Namen eines Moduls können importiert werden, indem
import zusammen mit from benutzt wird.
from EinModul import var1 # importiere nur var1
from EinModul import var1, var2 # importiere var1 und var2
from EinModul import var1, quadrat # erlaubt (keine Exportbeschränkung)
from EinModul import * # importiere (fast) alles
Mit der letzten Form werden alle Namen importiert, die nicht
mit _ beginnen.
Objektorientierte Programmierung
Allgemeines
- Objekte bieten Variablen und Funktionen (Methoden),
die auf diese Daten wirken.
Zum Bespiel soll ein Ofen die Variablen
- Temperatur (in °C)
- Klappe auf/zu
und die Funktionen
- klappe_oeffnen (kein Parameter)
- klappe_schliessen (kein Parameter)
- fuellen (Parameter: Material)
- aufheizen (Parameter: Endtemperatur in °C)
- abkühlen (kein Parameter)
haben.
- Es kann mehrere Objekte der selben Art (Instanzen)
geben (in unserem Beispiel mehrere Öfen), die unabhängig
voneinander sind.
- Die Schnittstelle zwischen Objekt und verwendendem Programmcode
soll nur offenlegen, was getan wird, aber möglichst nicht,
wie es getan wird. Letzteres bleibt
"Privatangelegenheit" des Objekts.
- Objekttypen (Klassen) können als Basis für
ähnliche, spezialisierte Typen dienen. Die Ableitung neuer
Klassen von bereits bestehenden nennt man Vererbung.
Übertragen auf das obige Beispiel könnte man aus der bestehenden
Klasse Ofen eine neue Klasse Umluftherd erzeugen,
bei der zusätzlich die Umluft ein- und ausgeschaltet werden kann.
Perl
- Eine Klasse in Perl ist ein Modul (genauer: ein
package) mit einigen Erweiterungen.
- Ein Konstruktor,
new, erzeugt ein neues
Objekt, eine Instanz der Klasse.
- Der Konstruktor erzeugt die der neuen Instanz zugeordneten Daten,
meist in Form einer assoziativen Liste. Das Schlüsselwort
bless ordnet das Objekt der Klasse zu, die dem
Konstruktor implizit als erstes Argument übergeben wird.
- Methoden des Objekts erhalten eine Referenz auf das gerade
bearbeitete Objekt implizit als erstes Argument.
- Die spezielle Liste
ISA (von "is a")
enthält die Namen der Klassen, von denen die im Modul definierte
Klasse abgeleitet ist.
- Unser oben genanntes Beispiel in Perl-Code:
# Ofen.pm
package Ofen;
sub new
{
my $class = shift; # erstes - implizites - Argument
my $self = {
temperatur => 20, # Raumtemperatur
klappe_auf => 0, # Klappe ist zu
inhalt => undef }; # kein Inhalt
bless $self, $class; # Instanz wird "gesegnet"
}
sub klappe_oeffnen
{
my $self = shift;
if( $self->{temperatur} > 20 )
{
print "Bitte vor dem Oeffnen der Klappe den Ofen abkuehlen!\n";
return;
}
$self->{klappe_auf} = 1;
}
sub klappe_schliessen
{
my $self = shift;
$self->{klappe_auf} = 0;
}
sub fuellen_mit
{
my $self = shift;
if( ! $self->{klappe_auf} )
{
print "Bitte vor dem Fuellen die Klappe oeffnen!\n";
return;
}
$self->{inhalt} = shift;
}
sub aufheizen
{
my $self = shift;
if( $self->{klappe_auf} )
{
print "Bitte vor dem Aufheizen die Klappe schliessen!\n";
return;
}
$self->{temperatur} = shift; # Temperatur als Argument
}
sub abkuehlen
{
my $self = shift;
$self->{temperatur} = 20;
}
1;
# ----------------------------------------------------------------
# Umluftherd.pm
package Umluftherd;
use Ofen;
@ISA = qw(Ofen); # erhalte alle Variablen
# und Methoden von Ofen
sub new
{
my $class = shift;
my $self = new Ofen;
$self->{umluft} = 0; # Umluft aus
bless $self, $class;
}
sub umluft_an
{
my $self = shift;
$self->{umluft} = 1;
}
sub umluft_aus
{
my $self = shift;
$self->{umluft} = 0;
}
1;
# ----------------------------------------------------------------
# ofentest.pl
#!/usr/bin/env perl
use Umluftherd;
$herd = new Umluftherd;
$herd->klappe_oeffnen;
$herd->fuellen_mit('Teig');
$herd->klappe_schliessen;
$herd->umluft_an;
$herd->aufheizen(250);
sleep 60*60; # eine Stunde backen
$herd->abkuehlen;
$herd->umluft_aus;
Python
- Eine Klasse in Python ist unabhängig von Modulen. Sie wird mit
der
class-Anweisung erzeugt.
- Der Konstruktor,
__init__, erzeugt eine neue Instanz.
Die Verbindung von Objektinstanz und Klasse geschieht implizit.
- Der Konstruktor kann die neue Instanz mit Werten initialisieren.
- Auch bei Python erhalten Methoden die Objektreferenz als
ersten Parameter.
- Eine Klasse kann von einer (oder mehreren) anderen erben,
indem der Name der "beerbten" Klasse als Argument der
class-Anweisung eingesetzt wird.
- Nach der Perl-Version folgt nun die Python-Variante des Beispiels.
# ofenmod.py
class Ofen:
def __init__(self):
self.temperatur = 20 # Raumtemperatur
self.klappe_auf = 0 # Klappe zu
self.material = None # Ofen ist leer
def klappe_oeffnen(self):
if self.temperatur > 20:
print "Bitte vor dem Oeffnen der Klappe den Ofen abkuehlen!"
return
self.klappe_auf = 1
def klappe_schliessen(self):
self.klappe_auf = 0
def fuellen_mit(self, material):
if not self.klappe_auf:
print "Bitte vor dem Fuellen die Klappe oeffnen!";
return;
self.material = material
def aufheizen(self, temperatur):
if self.klappe_auf:
print "Bitte vor dem Aufheizen die Klappe schliessen!"
return
self.temperatur = temperatur
def abkuehlen(self):
self.temperatur = 20
# ----------------------------------------------------------------
# umluftherdmod.py
import ofenmod
class Umluftherd(ofenmod.Ofen):
def __init__(self):
ofenmod.Ofen.__init__(self)
self.umluft = 0
def umluft_an(self):
self.umluft = 1
def umluft_aus(self):
self.umluft = 0
# ----------------------------------------------------------------
# ofentest.py
#!/usr/bin/env python
import umluftherdmod, time
herd = umluftherdmod.Umluftherd()
herd.klappe_oeffnen()
herd.fuellen_mit('Teig')
herd.klappe_schliessen()
herd.umluft_an()
herd.aufheizen(250)
time.sleep(60*60) # eine Stunde backen
herd.abkuehlen()
herd.umluft_aus()
Sprachphilosophien
Perl
Python
- Programme sollen leicht schreib-, les- und wartbar sein.
- Die Sprache soll sich erwartungsgemäß verhalten.
Beispielsweise liefert
L1 = [ 1, 2, [4, 5], 7 ]; L2 = L1[2]
die Liste [4, 5] in L2, während in Perl
@L1 = ( 1, 2, (4, 5), 7 ); @L2 = $L1[2];
eine Liste mit dem einzigen Element 4 erzeugt.
(Um die Wirkung des obigen Python-Codes zu erhalten, muss man
in Perl
@L1 = ( 1, 2, [4, 5], 7 ); @L2 = @{ $L1[2] };
schreiben.)
- Für ein Problem (von wenigen Codezeilen) sollte es
eine - offensichtliche - Lösung geben. Tatsächlich gibt es
i. Allg. auch in Python mehrere Möglichkeiten, aber
normalerweise weniger als in Perl.
Bewertung
Vorteile von Perl gegenüber Python
Vorteile von Python gegenüber Perl
- Python ist leichter zu erlernen, zu lesen und zu warten.
- Durch Ausnahmebehandlung wird die Abwicklung von
Laufzeitfehlern sehr erleichtert.
- Die Programmentwicklung in Python ist fast immer schneller,
weil die Bedeutung des gerade geschriebenen Codes leichter
erfassbar ist. Dadurch werden von vornherein weniger
(nicht-triviale) Fehler gemacht und die benötigte Zeit zur
Fehlersuche ist wesentlich geringer (vgl. die
Ausführungen zum erwartungsgemäßen Verhalten).
- Pythons Ansätze zur objektorientierten Programmierung
sind konsequenter als bei Perl. Python erlaubt bspw. mehr als
eine Instanzvariable und das Überladen von Operatoren, wodurch
generischer Code leichter erstellt werden kann.
Empfehlungen
Gleich gute Eignung
Für diese Anwendungsfelder sind beide Sprachen - von ihrer
"Ausstattung" her - etwa gleich gut geeignet:
- CGI-Programmierung
- andere Internet-Anwendungen (Emails abholen oder
verschicken, HTML-Quellcode parsen oder erzeugen etc.)
- "Tk-artige" Programme mit graphischer Oberfläche.
Für Perl gibt es Perl/Tk, für Python Tkinter.
- Perl und Python (Modul
re) verstehen dieselbe
Syntax von regulären Ausdrücken.
Kriterien für Perl
Folgende Kriterien sprechen für Perl:
- Es ist bereits verhältnismäßig viel Perl-Code im Rahmen
eines Projekts entstanden; ein Wechsel auf Python würde
bewirken, dass ein großer Teil neu geschrieben werden muss.
- Das Projekt hängt maßgeblich von Modulen ab, für die es
keine Entsprechung in Python gibt und die nicht leicht selbst
zu programmieren sind.
- Es sollen nur kurze "Einwegskripte" erstellt werden,
bei denen die Wartbarkeit unwichtig ist.
- Alle an dem Projekt beteiligten Programmierer sind sehr
vertraut mit Perl, aber nicht alle mit Python.
- In einem Web-Projekt ist der Provider fest vorgegeben und
unterstützt Python trotz Nachfrage nicht.
Kriterien für Python
Diese Kriterien sprechen besonders für Python:
- An dem Projekt arbeitet nicht nur eine Person; der Code soll
von verschiedenen Programmierern geschrieben und/oder gewartet
werden.
- Das Programm hängt von Python-Modulen ab, die es nicht für
Perl gibt und die nicht leicht neu zu implementieren sind.
- Der/die Programmierer arbeiten nicht "jeden Tag" an dem
Projekt. In diesem Fall sind Fehler bei der Entwicklung mit
Perl besonders häufig (Stichworte: Skalar- vs. Listenkontext,
verschachtelte Datenstrukturen, Konstruktoren und Vererbung).
- Der Pythoncode soll während der Entwicklung oder später
zusammen mit Java verwendet werden. Mit JPython (Implementation
von Python in Java) ist diese Verknüpfung besonders leicht.
Abschließende Bemerkungen
- Faustregel: Wenn es nicht besondere Gründe gibt, Perl zu
verwenden, sollte man ein Projekt mit Python in Angriff nehmen.
- Für beide (genauer: alle) Sprachen gilt: Erst
denken, dann schreiben :-)
- Auch in Python kann man unverständliche Programme schreiben,
wenn man nicht aufpasst.
- Die Zeit, die man in Python bei der "Implementation im
Kleinen" spart (Fehlersuche!), kann man zum Herausfinden von
besserem Programmdesign und besseren Algorithmen verwenden.
|