Python-Dienstprogramme

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

Dateisystem: os, os.path, cancelil

Die Module *os* und *os.path* enthalten viele Funktionen für die Interaktion mit dem Dateisystem. Mit dem *shutil*-Modul können Dateien kopiert werden.

  • Dokumentation zum OS-Modul
  • 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, verwenden Sie diese, um das Verzeichnis und den Dateinamen zusammen zu verwenden, um einen Pfad zu erstellen.
  • os.path.abspath(path) - bei einem Pfad wird eine absolute Form zurückgegeben, z.B. /home/nick/foo/bar.html
  • os.path.dirname(path), os.path.basename(path) --given dir/foo/bar.html, geben Sie den Verzeichnisnamen "dir/foo" und den Basisnamen "bar.html" zurück
  • os.path.exists(path) -- "true", wenn vorhanden
  • os.mkdir(dir_path) -- erstellt ein Verzeichnis, os.makedirs(dir_path) macht alle erforderlichen Verzeichnisse in diesem Pfad
  • downil.copy(source-path, dest-path) – Datei kopieren (drittpfad-Verzeichnisse 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 „import os“ aus und prüfen Sie dann mit den folgenden Befehlen, 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* bietet eine einfache Möglichkeit, einen externen Befehl auszuführen und die Ausgabe zu erfassen.

  • Dokumentation zu Modulen für Unterprozesse
  • output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) - führt den Befehl aus, wartet auf seine Beendigung und gibt den Ausgabetext zurück. Der Befehl wird mit der Standardausgabe und dem Standardfehler in einem einzigen Ausgabetext ausgeführt. Schlägt sie fehl, wird ein CalledProcessError ausgelöst.
  • Wenn Sie mehr Kontrolle über die Ausführung des Unterprozesses haben möchten, lesen Sie die Informationen zur Klasse „subprocess.popen“.
  • Es gibt auch einen einfachen subprocess.call(cmd)-Befehl, der den Befehl ausführt, die Ausgabe in die Ausgabe übergibt 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 Kontrolle an den Fehlerbehandlungscode übergibt. In diesem Abschnitt werden nur die grundlegendsten Verwendungen von Ausnahmen vorgestellt. Ein Laufzeitfehler kann beispielsweise darin bestehen, dass eine im Programm verwendete Variable keinen Wert hat (ValueError ... Sie haben diesen Fehler wahrscheinlich schon mehrmals gesehen) oder ein Fehler beim Öffnen von Dateien, weil keine Datei vorhanden ist (IOError). Weitere Informationen finden Sie in der Anleitung zu Ausnahmen und in der gesamten Ausnahmeliste.

Ohne Fehlerbehandlungscode (wie wir es bisher getan haben) wird das Programm durch eine Laufzeitausnahme einfach mit einer Fehlermeldung angehalten. Das ist ein gutes Standardverhalten, das Sie schon oft kennen. Sie können Ihrem Code eine „try/only“-Struktur hinzufügen, um Ausnahmen zu verarbeiten. Beispiel:

  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 möglicherweise eine Ausnahme auslöst. Der Abschnitt „Ausnahme:“ enthält den Code, der ausgeführt werden soll, wenn eine Ausnahme vorliegt. Wenn es keine Ausnahme gibt, wird der Abschnitt „außer:“ ü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 „außer IOError wie e: ..“ abrufen (e verweist auf das Ausnahmeobjekt).

HTTP -- urllib und urlparse

Das Modul *urllib.request* ermöglicht den URL-Abruf, sodass eine URL wie eine Datei aussieht, aus der Sie lesen können. Das Modul *urlparse* kann URLs auseinandernehmen und zusammenstellen.

  • Dokumentation zum Modul „urllib.request“
  • ufile = urllib.request.urlopen(url) -- gibt ein dateiähnliches Objekt für diese URL zurück
  • text = ufile.read() -- kann daraus lesen, wie eine Datei (readlines() usw. funktionieren auch)
  • info = ufile.info() - die Meta-Informationen für diese Anfrage. info.gettype() ist der MIME-Typ, z. B. "text/html".
  • baseurl = ufile.geturl() – ruft die "base"-URL für die Anfrage ab, die sich aufgrund von Weiterleitungen vom Original unterscheidet.
  • 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, und der Basis-URL 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 in 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 problemlos, beinhaltet jedoch keine Fehlerbehandlung, falls eine URL aus irgendeinem Grund nicht funktioniert. Im Folgenden finden Sie eine Version der Funktion, die eine „try/Ausnahme“-Logik hinzufügt, mit der eine Fehlermeldung ausgegeben wird, wenn der URL-Vorgang fehlschlägt.

Wenn urlopen() offenbar hängt, erlaubt Ihr System möglicherweise keinen direkten Zugriff auf einige HTTP-Adressen. Sie können dies prüfen, indem Sie versuchen, dieselbe URL mit wget oder curl abzurufen. Wenn diese Programme ebenfalls fehlschlagen, müssen Sie HTTP-Inhalte über einen Proxy-Dienst 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)

Training

Wenn Sie das Dateisystem und das Material zu externen Befehlen üben möchten, lesen Sie die spezielle Übung zum Kopieren. Wenn Sie das urllib-Material üben möchten, lesen Sie die Übung zum Protokollieren des Rätsels.