Gleich in welche Script- oder Programmiersprache der Einzelne einen Einstieg sucht, in
der Regel beginnt es mit einem einfachen kleinen "Hallo Welt" oder "Hello World" Programm. Die Listings und Codes
auf dieser Seite stellen in dieser Beziehung keine Ausnahme dar. Bleibt lediglich die Frage offen, ab wann ist
ein Programm ein Programm und ab wann kann eine Anwendung als Anwendung bezeichnet werden?
Nun, für die meisten Mitmenschen dürfte wohl eine beinahe leere Webseite, die lediglich in der oberen linken Ecke
zwei unformatierte Worte zur Begrüßung ausgibt, noch nicht ihren Vorstellungen von einer richtigen Webanwendung
entsprechen. Und dennoch, ohne dass bereits bei einem Test des ersten kleinen Listings ein Klient eine Anfrage
an einem Server senden und dieser die Anfrage entsprechend des in der Datei eingebetteten Codes beantworten würde,
würde halt auch kein "Hallo Welt" auf dem Monitor des Klienten ausgegeben werden.
Es sei angemerkt, mit Klient ist in der Online-Welt kein Ratsuchender gemeint, sondern der Rechner bzw. Computer
des Anwenders, wobei zwischen clientseitigen und serverseitigen Anwendungen unterschieden wird und ein Browser das
Ergebnis der serverseitigen Webanwendung präsentiert.
Betrachten wir uns zuerst zwei kleine Listings für den serverseitigen Einsatz, so erscheint es, als sollte der
Einstieg in Python selbst den bislang im Bereich der Programmierung noch unerfahrenen Leser problemlos gelingen.
Leider liegen die Tücken oftmals in den Details und zu diesen Details gehört, dass sich im Internet mit den Jahren
sehr viele in die Jahre gekommene Beispielcodes angesammelt haben. Beispielcodes, die unter einer neueren Python-Version
ohne kleine Änderungen nicht mehr lauffähig wären.
Für Einsteiger einen ersten Tipp an dieser Stelle. Übernehmen sie keine Beispiele mehr aus dem Internet, in denen
hinter der Print-Funktion die auszugebenen Werte nicht in runde Klammern gefasst wurden. Beispiele mit print ohne
Werte in (runde Klammern) beziehen sich noch auf frühere Versionen von Python und würden im Browser nur eine,
dem Einsteiger kaum etwas sagende, Fehlermeldung bewirken:
"End of script output before headers"
Erst durch einen Testauruf über IDLE –> File –> Open gefolgt von Run –> Run Module
ließe sich der Fehler eingrenzen:
SyntaxError
Missing parentheses in call to 'print'
Es sei angemerkt, die gemachte Aussage, keine ältere Python-Version zu benutzen, ist reichlich pauschal und für
den einen oder anderen Anwendungsfall oder Anwender kann es gute Gründe geben, Python in der Version 2.7 statt
3.6 oder neuer zu installieren. So riesig groß sind die Unterschiede nicht und die Version 2.7 wurde nicht zuletzt
wegen der großen Verbreitung noch bis zum 20. April 2020 durch Updates unterstützt. Wer sich dann erst einmal mit
beiden Versionen auskennt, kann kleinere Anwendung entweder für beide Versionen kompatibel gestalten oder diese zumindest
ohne größeren Aufwand umstellen.
Nur einem Einsteiger wird dies in den ersten Tagen nicht viel bringen, weil nicht gleich zu verstehen ist, warum
jedes zweite oder dritte im Web zu findende Beispiel nicht so wie beschrieben laufen will.
Alle weiteren Hinweise und Tipps für Einsteiger wurden den Beispielen zugeordnet und dürften für den einen oder
anderen Quereinsteiger aus einer anderen Script- oder Programmiersprache ebenfalls von Interesse sein.
Die Beispiele auf dieser Seite wurden mit Python in der Version 3.6 getestet, wobei die Installation von Python innerhalb einer bereits vorhandenen XAMPP-Umgebung erfolgte. Der sich daraus ergebene Pfad wurde für die Tests der ersten beiden Scripts unter Localhost wie folgt angepasst. Wenn Sie Python in einem anderen Verzeichnis installieren bzw. bereits installiert haben, müssen sie diesen Pfad entsprechend anpassen.
#!C:/xampp/python/python.exe
# -*- coding: utf-8 -*-
Es sei angemerkt, die Installation erfolgte unter Windows 10. Bei Linux, bei Mac oder
im Web würde der anzugebene Pfad etwas anders aussehen. Im Web sollten Sie im Zweifel ohnehin den vom Hoster vorgebende
Pfad benutzen.
Folgende Angaben beziehen sich auf Webpakete bei Strato und All-Inkl, dürften jedoch bei anderen Hostern gleich
oder ähnlich aussehen, insofern es sich beim Webserver um einen von einer Linux-Distribution umgebenen Apache-Webserver
handelt.
Beachtenswert, die Dateien müssen ins cgi-bin Verzeichnis abgelegt werden und beim Upload per FTP sollte nicht
vergessen werden, die Eigenschaften der Dateien auf Chmod 755 zu ändern, andernfalls wird dürfte nur eine Fehlerausgabe
erfolgen.
Unter Eigenschaften sind die Dateirechte auf chmod 755 einzustellen.
Weiterhin ist die Dateiendung (Extension) beachtenswert. Bei Strato wie bei All-Inkl
führten Aufrufe von mit der Endung *.py abgespeicherten Dateien nur zu serverseitigen Fehlermeldungen. Wurden
die Dateien mit der Endung *.cgi versehen, so ließen sie sich hingegen ohne Probleme aufrufen.
Im zurückliegenden Jahrzehnt und spätestens seit der Einführung von HTML5, hat sich weltweit die UTF-8-Zeichenkodierung
in allen Bereichen des Internets durchgesetzt. Wer zur Zeichenkodierung UTF-8 benutzen möchte, muss die entsprechenden
Angaben nicht nur dem Interpreter in der zweiten Zeile und dem Server in der dritten Zeile vom Script mitteilen,
sondern zusätzlich darauf achten, dass alle zum Script gehörenden Dateien unter UTF-8 gespeichert werden, insofern
diese Umlaute oder nicht zum ANSI-Zeichenvorrat gehörende Sonderzeichen enthalten.
Dateien konvertieren und unter UTF-8 speichern mit Notepad++.
Der Notepad++ diente im Beispiel nur als guter Allrounder, ein anderer geeigneter Editor
tut es auch, doch eine Auswahl möchten wir hier nicht treffen.
Es versteht sich eigentlich von allein, dass jedes Script vor einem ersten Test im Internet zuerst lokal getestet
werden sollte, um nicht den laufenden Serverbetrieb zu stören. Dazu gibt es unterschiedliche Möglichkeiten, von
denen wir zwei näher erläutern möchten.
Erste Möglichkeit: Wurde Python innerhalb einer bereits vorhandenen Xampp-Umgebung installiert,
sollte sich in dieser auf einer Verzeichnisebene mit dem htdocs-Verzeichnis bereits ein cgi-bin Verzeichnis befinden.
In diesem kann das erste kleine Script mit der Endung *.cgi abgelegt werden. Nachdem der Apache über das Control
Panel gestartet wurde, sollte es sich über
http://localhost/cgi-bin/script-name.cgi
im verwendeten Browser aufrufen lassen, wobei "Script-name" dabei gegen den Namen ihrer Datei ausgetauscht werden
muss.
Wer, aus welchen Gründen auch immer, den Wunsch verspürt, sein Script lieber mit der Endung *.py aufzurufen, muss
zuvor unter xampp –> apache –> conf in der Datei httpd.conf den Eintrag "AddHandler cgi-script"
entsprechend der gewünschten Extension ergänzen.
AddHandler cgi-script .cgi .pl .asp .py
Zweite Möglichkeit: Sie setzen mit Hilfe von Python selbst einen kleinen
Miniserver auf. Ein Script für einen Miniserver besteht nur aus wenigen Zeilen und sollte auch einen Einsteiger
kaum vor unüberwindbaren Hürden stellen.
Als ersten Schritt müssen Sie ohnehin ein Verzeichnis für ihre zukünftigen Scripts und Webapplikationen erstellen.
Dieses können Sie direkt in Ihrer neuen Python-Umgebung erledigen, zum Beispiel unter "C:/Python/webapps/", wobei
der Verzeichnisname "webapps" nur als Vorschlag zu verstehen ist. In diesem neu angelegten Verzeichnis legen Sie
nun noch ein Verzeichnis mit dem Namen "cgi-bin" an, welches auch so benannt werden sollte. Alle ausführbaren
Scripts fürs Web können Sie nun zukünftig in diesem cgi-bin Verzeichnis ablegen, das Script für den Miniserver
legen Sie hingegen auf einer Ebene mit diesem Verzeichnis ab.
Nur ein Beispiel: Ablage Miniserver und CGI-bin Verzeichnis
Der Name für das Script vom Miniserver ist in diesem Fall auf einem privat genutzten
Rechner frei wählbar, nur allgemein wird als Bezeichner httpd verwendet, wie z.B. httpd.exe für den Apache-Server.
Mit den Dateiendungen verhält es sich jedoch umgekehrt wie bei den getesteten Hostern. Wie weiter oben bereits
geschrieben, ließen sich im Web bei Strato und All-Inkl nur Scripts mit der Endung *.cgi aufrufen und unter Localhost
wurden ohne Änderung in der httpd.conf ebenfalls nur Anfragen mit der Endung *.cgi beantwortet.
Bei Python verhielt es sich umgekehrt, unser kleiner Testserver beantwortete nur Anfragen mit der Endung *.py.
Der Grund, unter Python –> Lib –> http ist die Datei server.py erreichbar und in dieser ist die
Klasse CGIHTTPRequestHandler mit der Methode is_python beheimatet. Wie der Name der Methode bereits verrät, findet
in dieser eine Überprüfung statt, ob es sich um eine Python Extension handelt. Wer unbedingt möchte, könnte diese
für eigene Tests wie im Bild die Endung ".cgi" ergänzen, was jedoch Programmierern mit reichlich Erfahrung vorbehalten
bleiben sollte.
Die Methode is_python in der Datei server.py
Zum eigentlichen Script des kleinen Testservers sei erwähnt, bei Verwendung von Ports
80 sollte sich eine fertig interpretierte Seite ohne zusätzliche Angabe eines Ports im Webbrowser aufrufen lassen.
Leider verhält es sich unter Windows 10 aber so, dass dieser Port in der Regel bereits durch andere Dienste belegt
wird, die zuvor deaktiviert werden müssten. Aus diesem Grund sind wir der allgemeinen, weit verbreiteten Verwendung
des Ports 8000 gefolgt. Beim Aufruf der Adresse im Browser muss dann explizit der Port mit angegeben werden, wodurch
die einzugebende URL dem folgenden Schema entsprechen sollte:
http://localhost:8000/cgi-bin/script-name.py
Alternativ lässt sich aber auch der Störenfried über den Task Manager suchen und deaktivieren. Als heißer Kandidat
kommt hier unter anderem der W3SVC WWW-
# Scriptname: miniserver.py from http.server import CGIHTTPRequestHandler, HTTPServer handler = CGIHTTPRequestHandler with HTTPServer(("", 8000), handler) as httpd: print("Server laeuft!") httpd.serve_forever()
Wer bis zu diesem Punkt alle Hinweise beachtet hat, sollte eigentlich mit den folgenden vier Codezeilen zumindest eine erste "Hallo Welt" Ausgabe im Web erzielen, vorausgesetzt Python steht innerhalb des eigenen Webpaketes zur Verfügung.
#!/usr/bin/python
# -*- coding: utf-8 -*-
print ("Content-Type: text/plain;charset=utf-8\n\n")
print ("Hallo Welt!")
Nur eine einfache und völlig unformatierte Ausgabe von Hallo Welt.
Nun dieses einfache Beispiel erfüllt sicherlich noch nicht die Ansprüche, die ein Anwender
oder Nutzer an ein neuzeitliches Webdesign stellt. Einer Erfüllung dieser Ansprüche kommt ein Programmierer jedoch
durch die Verwendung von mit HTML und CSS formatierten Ausgaben recht schnell näher. In diesem Beitrag möchten
wir jedoch nicht weiter auf die kreative Gestaltung des Designs einer Webanwendung eingehen, insofern diese Gestaltung
mehr mit HTML und CSS zu tun hat, als mit der Programmierung von Anwendungen.
An dieser Stelle zwei weitere Hinweise. Erster Hinweis, einen String über mehrere Zeilen lässt sich mit Umbrüchen
schreiben, wenn dieser String mit jeweils drei Anführungszeichen beginnt und endet. Und der zweite Hinweis, die
Zeile mit der Angabe des Zeichensatzes im HTML-Header ist eigentlich überflüssig, weil ein Browser diese nur
beachtet, wenn der Server keine Angaben zur Kodierung im HTTP-Header sendet. Doch für den Server wird ja die erste
Print-Funktion mit den entsprechenden Angaben aufgerufen.
#!/usr/bin/python # -*- coding: utf-8 -*- head = """ <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>Hallo Welt!</title> <style> body {text-align:center} h1 {font-family:cambria; font-size:24px; color:#c7a621} </style> </head> """ body = """ <body> <h1>Hallo Welt!</h1> </body> </html> """ print ("Content-Type: text/html;charset=utf-8\n\n") print (head) print (body)
Eine mit HTML und CSS formatierte Ausgabe.
Diese zweite Ausgabe sieht bereits gefälliger aus und der Code ließe sich beinahe beliebig erweitern. Ein kleiner Makel, wenn der String im Code wie im Beispiel eingerückt wird, so wird der String auch mit diesem Einrückungen in den Quelltext der Seite geschrieben. Doch dafür gibt es Lösungen, die sich mit der Zeit und den wachsenden Lernerfolgen von allein einstellen.
Bei Webanwendungen ist die Programmiersprache PHP nach wie vor sehr weit verbreitet und
im Zusammenspiel mit den clientseitigen Einsatzmöglichkeiten von JavaScript dürfte sich an dieser Beliebtheit so
schnell nichts ändern. Python wird aber besonders in den Bereichen interessant, in denen PHP kaum mithalten kann
und zu diesen Bereichen gehören Desktopanwendungen mit grafischen Oberflächen. Dank Tkinter, eine GUI-Erweiterung
nicht nur für Python, ist die Erstellung von Fenstern und Widgets kaum ein Problem.
Nebenbei bemerkt, GUI steht für grafische Benutzeroberfläche/Benutzerschnittstelle (graphical user interface).
Ob ein Leser sich unter Interface eher eine Oberfläche oder eher eine Schnittstelle vorstellt, bleibt jedem selbst
überlassen.
Zum Code des ersten Fensters sei bemerkt, es ginge noch spartanischer. So sind Angaben zum Titel, zur Geometrie
und zur Formatierung nicht zwingend erforderlich, machen ein Fenster jedoch erst ansehnlich. Ähnlich wie beim Webdesign,
besteht ein gewisser Spielraum bei der Gestaltung von Fenstern nebst grafischen Elementen, den jeder Entwickler
für sich selbst ausloten kann.
from tkinter import Tk, Label fenster = Tk() fenster.title("Erstes Fenster") fenster.geometry("420x120") Label(fenster, text = "Hallo Welt!", fg = "#c7a621", font = ("Cambria", 20, "bold"), pady = 38).pack() fenster.mainloop()
Ein erstes Fenster mit Python und Tkinter
Einen Punkt, den Einsteiger hingegen mehr Beachtung schenken sollten, sind die Importanweisungen bzw. die unterschiedlichen Varianten des Imports. Folgende Varianten sind möglich:
Auf die Unterschiede zwischen den einzelnen Varianten möchten wir an dieser Stelle nicht
näher eingehen, da es ein Thema für sich ist und ein tieferes Verständnis für Namensräume voraussetzt. Wichtig
ist lediglich, durch die Verwendung der ersten Variante lässt sich der Code in einem Script ein wenig übersichtlicher
gestalteten und der versehentlichen Überschreibung von noch im Modul schlummernden Objekten, bestehend aus Klassen
und Funktionen, vorbeugen.
Die zweite Variante mit den Sternchenimporten "from Modulname import *" sollte praktisch nie verwendet werden,
da hier unkontrolliert alles in den Namensraum des eigenen Scripts importiert wird, auch was nicht benötigt wird
oder versehendlich überschrieben werden könnte.
Falls wir hingegen bei der ersten Variante vergessen sollten, eine Klasse oder Funktion zu notieren, so ist das
kein Beinbruch, denn bei einem Testaufruf unseres Scripts unter IDLE –> Run –> Run Module erhalten
wir einen Hinweis auf noch fehlende Bezeichner in roter Schrift. Dieser Hinweis könnte dann etwa so aussehen könnte:
NameError: name 'Bezeichner' is not defined
Diesen Bezeichner kopieren wir uns und fügen ihn dann mit bei den zu importierenden Klassen und Funktionen ein. Auf Groß- und Kleinschreibung ist dabei unbedingt zu achten, da Python ebenfalls zwischen Groß- und Kleinschreibung unterscheidet und case sensitive reagiert.
from tkinter import Tk, Label, Button fenster = Tk() fenster.title("Zweites Fenster") fenster.geometry("420x180") fenstertext = Label(fenster, text = "Hallo Welt!", fg = "#c7a621", font = ("Cambria", 20, "bold"), pady = 38) fenstertext.pack() def wechsle_text(): fenstertext.config(text = "Hallo Python!") Button(fenster, text = "Wechsle Text", fg = "#ffffff", bg = "#808080", font = ("Cambria", 11), relief = "raised", padx = 20, command = wechsle_text).pack() fenster.mainloop()
Ein zweites Fenster mit einem Button zum Wechseln des angezeigten Textes.
Als abschließender Hinweis noch einen Tipp. Mit der Endung *.py öffnet sich bei den Fenstern zusätzlich noch ein Konsolenfenster im Hintergrund. Wenn Sie dieses zusätzlich Konsolenfenster im Hintergrund nicht möchten, speichern Sie einfach die Dateien mit der Endung *.pyw. Möglich ist lediglich das Windows nachfragt, mit welchem Programm die Dateien geöffnet werden sollen. Geben Sie in diesem Fall Python an.
Einstieg in Python
OOP mit Python
Codes & Tutorials
Kleines Projekt