programmiersprachen:python

Python

Python ist ein plattformunabhängige Skriptsprache in der man schnell, einfach und leicht programmieren kann. Auch auf Webservern wird es benutzt.

  1. Kommentare im Quellcode
  2. Informationen über Attribute anzeigen mit der dir()-Funktion, z. B.
    dir(str)
  3. Docstrings: __doc__ z. B.
    import sys
    print sys.__doc__
  4. PyDoc - bereitet docstrings auf:
    import sys
    help(sys.modules)

    :!: Es existiert mit dem skript pydocgui (bzw. auf Windows der Eintrag „Module Docs“ im Startmenu) auch eine Ausgabe in HTML

Nach dem Aufruf des Interpreters übersetzt der den Quelltext in maschinenunabhängigen Bytecode (abgespeichert hat er die Dateiendung .pyc) der dann zur Laufzeit von der Python virtual machine (PVM) ausgeführt wird.

Python2 ist veraltet. Es wird weiterhin verfügbar sein, Programme sollten jedoch explizit auf den python2-Interpreter verweisen wenn sie nicht mit 3 laufen.

Der Standard-Python-Interpreterpfad (Aufruf von python --version) sollte nun auf Version 3 landen.

Ablauf bei Debian/Ubuntu 1):

sudo update-alternatives --remove python /usr/bin/python2.7
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10
 
sudo apt install python3-pip
sudo apt remove python-pip #pip für version2
# ggf. sind lokal Versionen installiert, siehe whereis pip oder which -a pip
# "ln -s /usr/bin/pip /home/$USER/.local/bin/pip"
sudo ln -s /usr/bin/pip3 /usr/bin/pip
  1. Einrückungen sind nicht optional sondern Teil der Syntax!
  2. die Reihenfolge der Anweisungen richtet sich danach was hintereinander steht, außer es wird durch Kontrolflussanweisungen (if-Konstrukte etc.) anders bestimmt.
  3. Blöcke und Anweisungsgrenzen werden anhand von normalen Zeilenumbrüchen und Einrückungen erkannt
  4. Verbundanweisungen werden durch eine Kopfzeile (z.B. „if x:“) und natürlich durch Einrückungen der folgenden Zeilen bestimmt
  5. Leerzeichen in Anweisungen und Ausdrücken werden ignoriert, außer in Strings und bei Einrückungen
  6. Leerzeilenwerden in Dateien ignoriert, nur in der interaktiven Eingabe nicht
  7. Kommentare
    1. einzeilig: (mit Raute „#“ gekennzeichnet) Text wird bis zum Zeilenende ignoriert
    2. mehrzeilig: (mit drei Anführungzeichen „“„ gekennzeichnet) Text wird bis zu den nächsten drei Anführungszeichen ignoriert
  8. Dokumentationsstring (kurz docstrings) werden ignoriert aber von einigen Programmen angezeigt
    1. docstrings sind der erste Text der in einem Objekt oder einer Funktion.
      import sys
      print sys.__doc__
    2. PyDoc zeigt die docstrings noch einfacher an:
      import sys
      help(sys)

      Eine Ausgabe ist übrigens auch in html möglich.

Vorraussetzung: Ein Python-Interpreter ist auf dem System und im Suchpfad erreichbar.

  • interaktiv: python (Prompt wechselt zu “>>>„, bei mehrzeiligen Anweisungen, die mit einem einfachen Backslash „\“ am Zeilenende (oder mit drei Anführungszeichen) markiert werden, in “…„) hier gibt es ein paar Besonderheiten:
    • nur Python-Code eingeben, keine Systemkommandos
    • print anweisungen sind hier nicht explizit nötig, statt „print 'variable' “ reicht „variable“
    • keine Einrückungen verwenden, führende Leerzeichen führen zu Fehlern
  • Aufruf des Interpreters für eine Datei.py: „python Datei.py“ unter Windows schließt sich die Eingabeaufforderung nachdem das Programm fertig ist, um das zu umgehen könnte man am Ende ein
    raw_input()

    hinzufügen das auf einen Tastendruck wartet. Bricht allerdings das Programm vorher unerwartet mit einem Fehler ab, wird diese letzte Anweisung nicht mehr ausgeführt.

  • Linux: ausführbare Textdatei mit entsprechendem Vorspann entsprechend formulieren (unicode):
    #!/usr/bin/env python
    # -*- coding: utf-8 -*

    die erste Zeile kann auch spezifischer sein, ist dann allerdings nicht mehr so gut portabel!

    #!/usr/bin/python2.6
  • CPython: Referenzimplementierung, in portablem ANSI C geschrieben, und standardmäßig eingesetzt
  • Jpython: in Java implementiert, Quellcode wird in Java-Bytecode übersetzt und dieser dann in der Java virtual machine (JVM) ausgeführt. Damit verhalten sie Programme wie in Java geschrieben und können dementsprechend als Web-Applets und -Servlets fungieren ebenso die GUI-Elemente nutzen. Langsamer und weniger robust als CPython.
  • Ironpython: Ermöglicht eine Integration in das .Net-Framework
  • Psyco: Verhält sich anfangs ähnlich einer normalen PVM, ersetzt aber zur Laufzeit immer mehr Teile in maschinencode so dass Programme mit steigender Laufzeit immer performanter werden und sich der Geschwindigkeit von C annähern.
  • PyPy: PVM in einer Untermenge von Python (Restricted Python) implementiert um als Framework die Übersetzung beliebiger Skriptsprachen in schnelle Zielsprache zu ermöglichen.
  • Binärdateien erzeugen : Windows: py2exe MacOS py2app und freeze für Unix-artige Systeme.

Kommentare:

  • einzeilig: # Kommentar
  • mehrezeilig: “„“ Kommentar „“„

Programmstruktur

  • Programme → Module → Anweisungen → Ausdrücke → bilden und verarbeiten Objekte

Variablen sind immer Zeiger auf unveränderliche Objekte, Ausnahmen sind u.a. Listen und Dictionaries wo Objekte an Ort und Stelle verändert werden. Nicht mehr benutzte Objekte werden freigegeben (garbage collection). Der Typ einer Variable kann mit type ausgegeben werden:

 type(Variable)

Es gibt 3 Kategorien von Typen (und Operationen):

  1. Abbildungen: Indizierung durch Schlüssel etc.
  2. Sequenzen: unterstützt werden Indizierung, Verkettung, Teilbereiche etc.
  3. Zahlen: unterstützt werden Addition, Multiplikikation etc.

Dabei unterscheiden sich

  1. veränderliche Typen die an Ort und Stelle geändert werden können und
  2. unveränderliche Typen für deren Änderung ein neues Objekt erzeugt werden muss.
Objekttyp (Erzeugungs-) Beispiele
Zahlen 2)3)
Normale Ganzzahl 4) 1234, -48, 0
Lange Ganzzahl 5) 99999999999999999L
Fließkommazahl 6) 1.23, 3.14e-10, 5E123, 5.0e+234
Oktale und Hexadezimale Literale 7) 0167, 0xf3f, 0XFF
Komplexe Zahlen 8)) 3+4j, 3.0+4.0j, 3J
Strings (=Zeichenketten)
Leerer String a = ''
einfache und doppelte Anführungszeichen: kennzeichnen Text, beide Varianten sind gleichwertig 9) „text“ oder 'text'
dreifache Anführungszeichen: beliebig lange Texte
print """ erste Zeile
zweite Zeile """
Escape-sequenzen
print "Anführungszeichen \" sind toll "

spezielle Zeichen wie \n für Zeilenumbruch oder \t für Tabulator gelten außerdem

rohe strings (python escaped automatisch) pfad = r'C:\ordner\datei.txt'
Unicode strings 10) u'deutsche Umlaute in unicode: öäü'
Listen - eine Sammlung beliebiger Objektarten
Zugriff auf einzelne Elemente
print liste[0]
Listen reagieren bei Operatoren ähnlich wie Strings
Länge bestimmen
len([1, 2, 3])

ergibt drei

Verkettung
[1, 2, 3] * [4, 5, 6]

ergibt [1, 2, 3, 4, 5, 6]

Enthalten?
3 in [1, 2, 3]

ergibt „True“

Iteration
for x in [1, 2, 3]: print x
Dictionaries (=Wörterbücher weil Schlüssel-Wert-paar) bzw. assoziative Arrays
Beschreibung/Hinweise Wörterbücher sind Container, sie speichern nicht die Objekte an sich, sondern die Pointer auf die Werte. Schlüssel in einem dictionary können ein beliebiges Objekt sein, solange es immutable und hashbar ist 11). Somit sind beispielsweise Listen nicht als Schlüssel möglich. Schlüssel sind oft string, aber auch integer,tupel oder unicode werden benutzt. Außerdem müssen Schlüssel auch nicht homogen sein, hier können mehrere Datentypen vermischt werden!))
Initialisieren
exampledict = {}
Wertzuweisung (Schlüssel)
exampledict = {1: "eins", 2: "zwei", 3: "drei"}
Anzahl Einträge bestimmen FIXME
 
Alle Werte anzeigen
exampledict

Ausgabe:

{1: 'eins', 2: 'zwei'}
Zugriff auf einzelne Elemente
exampledict[1]

wenn der Schlüssel als string definiert worden wäre:

exampledict["1"]
einzelne Elemente (hier Schlüssel 4 mit Wert „vier“) hinzufügen
exampledict[4] =  "vier"
einzelne Elemente (hier Schlüssel 3) löschen
exampledict.del(3)
alle Elemente/das komplettes dictionary löschen
exampledict.clear()
Werte verändern 12) FIXME
Schlüsselnamen verändern Geht nur über löschen/neu setzen weil die Schlüsselnamen selbst unveränderbar sind:
oldval = exampledict[4]
del exampledict[4]
exampledict[4] = "Vier"
Iteration
for exampledict in [1, 2]: print exampledict
Wörterbücher - nicht existierende Einträge abfangen
Methode 1: EAFP (Easier to Ask Forgiveness than Permission) - Wert-Abfrage mit abfangen der Exception
try:
	print exampledict[4]
except KeyError:
	print "not found"
Methode 2: LBYL (Look Before You Leap) - Schauen ob Schlüssel existiert und dann Wertabfrage oder Meldung ohne Wertabfrage
if 4 in exampledict:
	print exampledict[4]
else:
	print "not found"

Alternativ wäre die if-Zeile auch so möglich:

exampledict.has_key(4)

hier wird dann False zurückgegeben folglich in in else verzweigt.

Methode 3: get-Methode von dict mit oder ohne default-Wert
ergebnis = exampledict.get(4, "not found")
print ergebnis
Alias zu einem dictionary erzeugen
exampledict2 = exampledict
Shallow-copy 13) von einem dictionary erzeugen
exampledict2 = exampledict.copy()
Eingenständige (rekursive) Kopie von einem dictionary erzeugen
exampledict2 = copy.deepcopy(exampledict)
Ausgabesortierung
Tupel
FIXME
Dateien
FIXME
Mengen
FIXME

explizite Typumwandlung:

  • als Zahl: int(23)
  • als String: str(23)
  • als float: float(„1.234E-100“)

Ausdrucksoperatoren:

  • einfache Arithmetik: + * / -
  • Potenzierung: (2 hoch 100)
    print 2 ** 100
  • >> FIXME
  • Verkettung |
    print 'hello ' + 'world'
  • einfachster Fall:
    if x == 1:
      print "x ist gleich 1."
  • komplexester Fall mit allen optionalen Bestandteilen:
    if x == 1:
      print "x ist gleich 1."
    elif x == 0
      print "x ist gleich 0."
    else:
      print "x ist weder 1 noch 0."
  • Mehrfach-Verzweigung (ähnlich switch/case in anderen Sprachen) sind mit „elif“ Konstrukten (s. o.) abbildbar, zusätzlich kann das durch Indizierung in Dictionaries oder Suche in Listen evtl. flexibler gestaltet werden:
    auswahl = "Hilfe"
    print {"keineHilfe": 0,
    "Hilfe": 1,
    "Sonstiges": 9}[auswahl]
  • Standardwert setzen - mit has_key() oder get():
    auswahl = {"keineHilfe": 0,
    "Hilfe": 1,
    "egal": 3}
    print auswahl.get("Antwort nicht enthalten", "Sonstiges")

Folgende zwei Schleifenkonstrukte sind die wichtigsten, es gibt noch allerdings noch andere Funktionen wie map, reduce, filter, den Elementtest mit in, List Comprehensions usw.

  • while-Schleife: führt immer wieder einen Block solange die Bedingung in Kopfzeile erfüllt ist (ein wahren Wert ergibt). Wenn er anfangs nicht erfüllt ist, wird nichts ausgeführt also spricht man von einer kopfgesteuerten Schleife.
    • continue - springt zur Kopfzeile der innersten Schleife
    • Beispiel:
      a = 0
      while a < 10:
          a = a + 1   # Kurzschreibweise: a += 1    
          if a == 5:
              print "die 5 gebe ich nicht aus!"
              continue
          print a
      else:
          print "Schleife normal beendet"
    • break - springt aus der innersten Schleife heraus: Beispiel wo die Schleife nicht normal beendet wird, weil bei der 5 abgebrochen wird
      a = 0
      while a < 10:
          a = a + 1   # Kurzschreibweise: a += 1    
          if a == 5:
              print "die 5 gebe ich nicht aus!"
              break
          print a
      else:
          print "Schleife normal beendet"
    • pass - tut nichts, dient als Platzhalter
    • „else:“ Block nach Schleife: wird ausgeführt wenn Schleife normal beendet wird (ohne break)
  • for-Schleife: läuft über alle Elemente eines geordneten (Sequenz-) Objekts (z. B. Strings, Listen und Tupel)
    • Beispiel:
      for a in ["erster " "zweiter " "dritter"]:
        print a
    • mit range, xrange und zip können Indices für Zählschleifen generiert werden
    • umgekehrte Iteration gehen mit reverse

beim Aufruf:

  • Normales Argument kommen mit dieser Positionierung in der Funktion an:
    funktionsname(wert1, wert2)
  • Argumente mit Namensangabe
    funktionsname(argument1=wert1, argument2=wert2)

    in diesem Fall gleichbedeutend:

    funktionsname(argument2=wert2, argument1=wert1)

in der Funktionsdeklaration:

  • normales Argument, Vergleich nach Name oder Position:
    def funktion(wert)
  • Parameter (name) hat Vorgabewert (wert) falls keiner übergeben wurde:
    def funktion(name=wert)
  • Verbleibende Argumente in ein Tupel speichern:
    def funktion(*tupel)
  • Verbleibende Argumente in ein dictionary speichern
    def funktion(**dict)

Eine Sonderform ist der lamba-Ausdruck, er wird oft als inline-Funktion benutzt. Damit können Funktionen an Stellen aufgerufen werden, wo sonst kein „def“ erlaubt wäre.

Anstatt (Ein- und Ausgabe der interaktiven Shell):

>>> def function(a, b, c): return a + b + c
... 
>>> function(1, 2, 3)
6

geht genauso:

>>> rechne = lambda a, b, c: a + b + c
>>> rechne
<function <lambda> at 0x87096f4>
>>> rechne(1, 2, 3)
6

Import von Modulen

  • Dateiendungen und Pfade müssen weggelassen werden
  • jede .py-Datei kann als Modul importiert werden:
    import modulename
  • ein import findet nur bei ersten mal statt, ein erneuter Import muss so erfolgen:
    reload (modulename)

Als Vorbereitung muss python-dev bzw- python3-dev installiert werden, andernfalls kommt diese Fehlermeldung:

fatal error: Python.h: Datei oder Verzeichnis nicht gefunden

Installieren von Dritt-Anbietermodulen

Fall 1: Distutils-Pakete (Standard)
  • Linux: python setup.py install
  • Windows (cmd): setup.py install
Fall 2: Einfache .py-Dateien

Hier ist lediglich ein kopieren in das „site-packages“ Unterverzeichnis nötig:

Siehe auch: Mod_python Manual und Introducing mod_python.

Zuerst muss einmal mod_python

  1. installiert
  2. aktiviert sein (a2enmod mod_python)
  3. und für die Verarbeitung von .py-Dateien benutzt werden. Um für das Verzeichnis /var/www/pythondir Python zu aktivieren, braucht es nur wenig Code:
<Directory /var/www/pythondir> 
  AddHandler mod_python .py
</Directory>

Natürlich kann man mod_python auch global aktivieren, dann lässt man die Einschränkung auf ein einziges Verzeichnis eben weg.

Andere Optionen (z.B. PythonHandler Dateiname (ohne .py); PythonDebug On usw.) sind auch möglich.


2)
Zahlen haben bei CPython die gleiche Genauigkeit wie der Compiler der den Python-Interpreter erstellt hat
3)
Erweiterung NumPy bietet zusätzliche Werkzeuge und z. B. einen Matrix-Datentypen
4)
in C: long; intern als C-longs implementiert, d.h. mindestens 32Bit
5)
unbegrenzt; L seit Python 2.2 nicht mehr nötig da Zahlen automatisch von normal in lange Zahlen konvertiert werden
6)
e oder E kennzeichnet den Exponenten mit oder ohne Vorzeichen; intern als C-double implementiert
7)
Klein oder Großbuchstaben sind gleichwertig
8)
Realteil (optional) + Imaginärteil (endet of j oder J
9)
können aber auch benutzt werden um das jeweils andere Zeichen als Teil des strings zu kennzeichnen
print ' dieses Anführungszeichen " ist Teil des strings'
10)
ab python 3 sind alle strings unicode; auch wide-character strings genannt. Explizite Konvertierung von unicode zu normal mit
str(u'unicodetext)
bzw. von normal nach unicode:
unicode ('normal')
11)
also eine Methode __hash__ definiert haben. Das kann mit
hash(Variable)
überprüft werden.
12)
Anmerkung: Mit der append-Methode können auch Daten angehängt werden
13)
die Wörterbücher teilen sich evtl. gemeinsame Werte, Achtung Fehlerquelle!
14) , 15)
Byte-Code erzeugen damit die Module schneller geladen werden:
python -c 'import compileall; compileall.compile_path()'