Python-Dienstprogramme

In diesem Abschnitt werfen wir einen Blick auf einige der vielen Standard-Dienstprogrammmodule von Python, um häufige Probleme zu lösen.

Dateisystem – os, os.path, Shutil

Die Module *os* und *os.path* enthalten viele Funktionen für die Interaktion mit dem Dateisystem. Das Modul *shutil* kann Dateien kopieren.

  • os modul dokumente
  • filenames = os.listdir(dir) -- Liste der Dateinamen in diesem Verzeichnispfad (ohne . und ...). Die Dateinamen sind nur die Namen im Verzeichnis, nicht ihre absoluten Pfade.
  • os.path.join(dir, filename) - Bei einem Dateinamen aus der obigen Liste wird dies verwendet, um das Verzeichnis und den Dateinamen zu einem Pfad zusammenzuführen.
  • os.path.abspath(path) - gibt bei einem Pfad eine absolute Form zurück, z.B. /home/nick/foo/bar.html
  • os.path.dirname(path), os.path.basename(path) - Bei Verwendung von dir/foo/bar.html wird der dirname "dir/foo" zurückgegeben. und Basisname „bar.html“
  • os.path.exists(path) -- "true", falls vorhanden
  • os.mkdir(dir_path) - erstellt ein dir, os.makedirs(dir_path) erstellt alle erforderlichen dirs in diesem Pfad
  • hideil.copy(source-path, dest-path) - Kopiert eine Datei (Verzeichnisse des Zielpfads sollten vorhanden sein)
## Example pulls filenames from a dir, prints their relative and absolute paths
def printdir(dir):
  filenames = os.listdir(dir)
  for filename in filenames:
    print(filename)  ## foo.txt
    print(os.path.join(dir, filename)) ## dir/foo.txt (relative to current dir)
    print(os.path.abspath(os.path.join(dir, filename))) ## /home/nick/dir/foo.txt

Das Erkunden eines Moduls funktioniert gut mit den integrierten Python-Funktionen help() und dir(). Führen Sie im Interpreter den Befehl „import os“ aus und verwenden Sie dann diese Befehle, um zu sehen, was im Modul verfügbar ist: dir(os), help(os.listdir), dir(os.path), help(os.path.dirname).

Externe Prozesse ausführen - Unterprozess

Das Modul *subprocess* ist eine einfache Möglichkeit, einen externen Befehl auszuführen und seine Ausgabe zu erfassen.

  • Unterprozessmodul-Dokumente
  • Ausgabe = subprocess.check_output(cmd, stderr=subprocess.STDOUT) - führt den Befehl aus, wartet auf dessen Beenden und gibt seinen Ausgabetext zurück. Der Befehl wird mit der Standardausgabe und den Standardfehlern zu einem Ausgabetext ausgeführt. Wenn er fehlschlägt, wird ein CalledProcessError ausgelöst.
  • Wenn Sie mehr Kontrolle über die Ausführung des Unterprozesses haben möchten, sehen Sie sich die Klasse subprocess.popen an.
  • Es gibt auch einen einfachen subprocess.call(cmd)-Befehl, der den Befehl ausführt, die Ausgabe in der Ausgabe ausgibt und den Fehlercode zurückgibt. Dies funktioniert, wenn Sie den Befehl ausführen möchten, aber die Ausgabe nicht in Ihre Python-Datenstrukturen erfassen müssen.
import subprocess

## Given a dir path, run an external 'ls -l' on it --
## shows how to call an external program
def listdir(dir):
  cmd = 'ls -l ' + dir
  print("Command to run:", cmd)   ## good to debug cmd before actually running it
  (status, output) = subprocess.getstatusoutput(cmd)
  if status:    ## Error case, print the command's output to stderr and exit
    sys.stderr.write(output)
    sys.exit(status)
  print(output)  ## Otherwise do something with the command's output

Ausnahmen

Eine Ausnahme stellt einen Laufzeitfehler dar, der die normale Ausführung in einer bestimmten Zeile anhält und die Steuerung an den Fehlerbehandlungscode übergibt. In diesem Abschnitt werden nur die grundlegendsten Verwendungsmöglichkeiten von Ausnahmen erläutert. Ein Laufzeitfehler könnte beispielsweise darin bestehen, dass eine im Programm verwendete Variable keinen Wert hat (ValueError ..., das ist Ihnen wahrscheinlich schon einmal aufgefallen) oder dass ein Fehler beim Dateiöffnen auftritt, weil keine Datei vorhanden ist (IOError). Weitere Informationen finden Sie in der Anleitung zu Ausnahmen und in der vollständigen Ausnahmeliste.

Ohne Fehlerbehandlungscode (wie bisher) stoppt eine Laufzeitausnahme einfach das Programm mit einer Fehlermeldung. Das ist ein gutes Standardverhalten, das Sie schon oft erlebt haben. Sie können „try/except“ hinzufügen, um Ausnahmen zu verarbeiten:

  try:
    ## Either of these two lines could throw an IOError, say
    ## if the file does not exist or the read() encounters a low level error.
    f = open(filename, 'rb')
    data = f.read()
    f.close()
  except IOError:
    ## Control jumps directly to here if any of the above lines throws IOError.
    sys.stderr.write('problem reading:' + filename)
  ## In any case, the code then continues with the line after the try/except

Der Abschnitt „try:“ enthält den Code, der eine Ausnahme auslösen könnte. Der Abschnitt außer: enthält den Code, der ausgeführt werden soll, wenn es eine Ausnahme gibt. Gibt es keine Ausnahme, wird der Abschnitt "except:" übersprungen, d. h., dieser Code dient nur der Fehlerbehandlung und nicht der normalen Groß- und Kleinschreibung. Sie können einen Zeiger auf das Ausnahmeobjekt selbst mit der Syntax "except IOError as e: .." erhalten. (e verweist auf das Ausnahmeobjekt).

HTTP -- urllib und urlparse

Das Modul *urllib.request* bietet URL-Abruf, sodass eine URL wie eine Datei aussieht, aus der Sie lesen können. Das Modul *urlparse* kann URLs zerlegen und zusammensetzen.

  • urllib.request Moduldokumente
  • ufile = urllib.request.urlopen(url) -- gibt für diese URL eine Datei wie ein Objekt zurück
  • text = ufile.read() - kann daraus lesen, wie eine Datei (readlines() usw.).
  • info = ufile.info() -- die Meta-Informationen für diese Anforderung. info.gettype() ist der MIME-Typ, z.B. "text/html"
  • baseurl = ufile.geturl() - ruft die "base" ab URL für die Anfrage, die sich aufgrund von Weiterleitungen vom Original unterscheiden kann
  • urllib.request.urlretrieve(url, filename) - lädt die URL-Daten in den angegebenen Dateipfad herunter
  • urllib.parse.urljoin(baseurl, url) - bei einer URL, die vollständig sein kann oder nicht, und bei der baseurl der Seite, von der sie stammt, wird eine vollständige URL zurückgegeben. Verwenden Sie oben „geturl()“, um die Basis-URL anzugeben.

Alle Ausnahmen befinden sich unter urllib.error.

from urllib.request import urlopen

## Given a url, try to retrieve it. If it's text/html,
## print its base url and its text.
def wget(url):
  ufile = urlopen(url)  ## get file-like object for url
  info = ufile.info()   ## meta-info about the url content
  if info.get_content_type() == 'text/html':
    print('base url:' + ufile.geturl())
    text = ufile.read()  ## read all its text
    print(text)

Der obige Code funktioniert einwandfrei, beinhaltet jedoch keine Fehlerbehandlung, falls eine URL aus irgendeinem Grund nicht funktioniert. Im Folgenden sehen Sie eine Version der Funktion, die die "try/except"-Logik ergänzt, um eine Fehlermeldung auszugeben, wenn der URL-Vorgang fehlschlägt.

Wenn urlopen() aufhängt, erlaubt Ihr System möglicherweise keinen direkten Zugriff auf einige HTTP-Adressen. Sie können dies überprüfen, indem Sie versuchen, dieselbe URL mit wget abzurufen oder curl. Sollten diese Programme ebenfalls fehlschlagen, müssen Sie HTTP-Inhalte über einen Proxy abrufen. . Das Konfigurieren des Proxyzugriffs wird in dieser Anleitung nicht behandelt.

## Version that uses try/except to print an error message if the
## urlopen() fails.
def wget2(url):
  try:
    ufile = urlopen(url)
    if ufile.info().get_content_type() == 'text/html':
      print(ufile.read())
  except IOError:
    print('problem reading url:', url)

Übung

Unter Spezialübung zum Kopieren können Sie das Dateisystem und das Material zu externen Befehlen üben. Informationen zum Üben des urllib-Materials finden Sie unter Log-Rätselübung.