Home
Navigation
Impressum
Coder Welten - Programmierung und Optimierung
Coder Welten
 
 

 

 

'Hallo Welt' in oder mit Python 3

Beispiele für simple Web- und Desktopanwendungen

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 Bezie­hung keine Ausnahme dar. Bleibt lediglich die Frage offen, ab wann ist ein Pro­gramm 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 ent­sprechen. 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 client­seitigen 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 Ände­rungen 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, Fehlermel­dung 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 benut­zen, 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 wird nicht zuletzt wegen der großen Verbreitung noch weiterhin 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 im Web zu findende Beispiel nicht so wie beschrieben laufen will.

Alle weiteren Hinweise und Tipps für Einsteiger wurden den Beispielen zuge­ordnet und dürften für den einen oder anderen Quereinsteiger aus einer anderen Script- oder Programmiersprache ebenfalls von Interesse sein.

Beispiele für Webanwendungen

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 Datei­en auf Chmod 755 zu ändern, andernfalls wird dürfte nur eine Fehlerausgabe erfolgen.

Eigenschaften Dateirechte chmod 755
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 verse­hen, 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 durch­gesetzt. Wer zur Zeichenkodierung UTF-8 benutzen möchte, muss die entspre­chenden 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 ent­halten.

Dateien konvertieren
Dateien konvertieren und unter UTF-8 speichern mit Notepad++.

Der Notepad++ diente im Beispiel nur als guter Allrounder, ein anderer ge­eigneter 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 Server­betrieb 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 ausge­tauscht 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 ge­wünsch­ten Extension ergänzen.

AddHandler cgi-script .cgi .pl .asp .py

Zweite Möglichkeit: Sie setzen mit Hilfe von Python selbst einen kleinen Mini­ser­ver 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 Ver­zeichnisname "webapps" nur als Vorschlag zu verstehen ist. In diesem neu ange­legten 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 Mini­server legen Sie hingegen auf einer Ebene mit diesem Verzeichnis ab.

Ablage Miniserver und CGI-bin Verzeichnis
Nur ein Beispiel: Ablage Miniserver und CGI-bin Verzeichnis

Der Name für das Script vom Miniserver ist in diesem Fall auf einem privat genutz­ten 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 ge­schrieben, 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 vorbe­halten bleiben sollte.

Ein Bild der Methode is_python
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 allge­meinen, weit verbreiteten Verwendung des Ports 8000 gefolgt. Beim Aufruf der Adresse im Browser muss dann explizit der Port mit angegeben werden, wodurch die einzu­gebende 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-Publishingdienst in Frage. Nach der Deaktivierung kann dann im Listing aus der 8000 eine 80 gemacht werden und die URL ohne Port in den Browser eingegeben werden.

# 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 erzie­len, 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!")

Einfache Ausgabe von 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 Weban­wendung 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 formatierte Ausgabe
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 ein­gerückt wird, so wird der String auch mit diesem Einrückungen in den Quell­text der Seite geschrieben. Doch dafür gibt es Lösungen, die sich mit der Zeit und den wachsenden Lernerfolgen von allein einstellen.

Beispiele für Desktopanwendungen

Bei Webanwendungen ist die Programmiersprache PHP nach wie vor sehr weit ver­breitet und im Zusammenspiel mit den clientseitigen Einsatzmöglichkeiten von Java­Script 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 Ober­flä­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 Benutzer­ober­fläche/Benutzer­schnitt­stelle (graphical user interface). Ob ein Leser sich unter Interface eher eine Ober­flä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 erforder­lich, machen ein Fenster jedoch erst ansehnlich. Ähnlich wie beim Webdesign, besteht ein gewisser Spielraum bei der Gestaltung von Fenstern nebst grafischen Elemen­ten, 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()

Erstes Fenster mit Python und Tkinter
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:

1. from Modulname import Bezeichner für Klassen oder Funktionen
2. from Modulname import *
3. import Modulname
4. import Modulname as Kürzel

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 Ver­stä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 schlum­mernden Objekten, bestehend aus Klassen und Funktionen, vorbeu­gen.
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 ver­sehendlich ü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 impor­tierenden Klassen und Funktionen ein. Auf Groß- und Kleinschreibung ist dabei unbedingt zu achten, da Python ebenfalls zwischen Groß- und Kleinschreibung unter­scheidet 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 Python und Tkinter
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 welchen Programm die Dateien geöffnet werden sollen. Geben Sie in diesem Fall Python an.

 

 

Copyright © Verlag Horst Müller - Stendal - 2006 - Impressum - Datenschutz - Nutzungsbedingungen