Eingabe und Ausgabe
Kommandozeile
- alle Kommandozeilenargument sind über sys.argv zugänglich
- sys.argv[0] enthält den Namen der Applikation
- das Progrämmchen stellt die Kommandozeile dar
import sys for ( index,value ) in enumerate( sys.argv ): print "sys.argv[%d] = %s" % (index,value)
- ein Aufruf der Form
python commandline.py dies ist nur ein Test
führt zu folgender Ausgabe:
sys.argv[0] = commandline.py sys.argv[1] = dies sys.argv[2] = ist sys.argv[3] = nur sys.argv[4] = ein sys.argv[5] = Test
- die built-in Funktion enumerate ist ein praktisches Handwerkzeug, um sich zu einer Sequenz sowohl den Index wie auch den Wert ausgeben zu lassen
>>> for (i,v) in enumerate(["eins","zwei","drei"]): ... print i, v ... 0 eins 1 zwei 2 drei
- schreibe ein kleines Programm, das RainerGrimm als Kommandozeilenargument erhält und folgende Ausgabe erzeugt:
Mein Name ist RainerGrimm - sobald es anspruchsvoller wird, sollte die Libraries getopt oder insbesondere optparse für das Parsen der Kommandozeile benützen
Dateien
- das Dateihandling ist schon in der Kernfunktionalität enthalten
- durch f= open('Datei'[,'Modus']) wird eine Datei geöffnet
- für Modus gibt es folgende Optionen
- r (read) fürs Lesen
- w (write) fürs Schreiben
- a (append) fürs Anhängen
- b (binary) für binäre Lesen oder Schreiben
- + (update) um mit einer Datei sowohl Lesen als auch Schreiben zu können
beim Kontextwechsel vom Schreiben zum Lesen muss immer erst der Schreibpuffer geflusht werden, um ein definiertes Verhalten zu gewährleisten
- das folgende Programm besteht aus folgenden Schritten
- lege die Datei MeineTestDatei zum Schreiben und Lesen an
- schreibe den String "das ist nur ein Test"
- flushe den Output schreibe den String in die Datei
- setze den Dateizeiger auf den Anfang der Datei
- lies die ganze Datei ein
>>> testDatei=open("MeineTestDatei","w+") >>> print >> testDatei, "das ist nur ein Test" >>> testDatei.flush() >>> testDatei.seek(0) >>> print ( testDatei.readlines() ) ['das ist nur ein Test\n']
- per Default wird eine Datei zum Lesen geöffnet
- der Unterschiede zwischen den Modi "r+" und "w+" zum Lesen und Schreiben einer Datei ist, daß durch "w+" eine neue Datei angelegt wird, während mit "r+" die Datei zum Lesen geöffnet wird, also insbesondere vorhanden sein muß
Methoden
- das Dateiobjekt unterstützt folgendes Interface
Methode Beschreibung file.read([n]) liest die ganze Datei, falls kein n angegeben wurde,
sonst höchstens n Bytesfile.readline([n]) lies ein ganze Zeile, falls kein n angegeben wurde.
Andernfalls maximal n Bytesfile.readlines() lies alle Zeilen und gib sie als Liste zurück file.xreadlines() gibt eine zu iterierende Sequenz aller Zeilen zurück, ohne alle Zeilen vollständig im Speicher zu halten file.write(s) schreibe den String s file.writelines(l) schreibe alle Strings der List l file.close() schliesse die Datei file.tell() gibt den aktuellen Dateizeiger zurück file.seek(offset[,where]) setze den Dateizeiger auf die angegebene Position file.isatty() gibt 1 zurück, falls file ein interaktives Terminal ist file.flush() flushe den Ausgabepuffer file.truncate([size]) verkürzt die Datei auf maximal size Bytes file.fileno() gibt den filedescriptor als Integer zurück
Lesen
- um durch die Zeilen einer Datei zu iterieren, bietet sich bei kleinen Dateien
for line in file.readlines()
und für große Dateien der effizienterer Ausdruck
for line in file
an, da dieser lazyist
- mittels der built-in Funktion type sieht man einfach die semantische Unterschiede der drei Methoden, um Dateien zu lesen
>>> type ( open("/etc/passwd").read() ) <type 'str'> >>> type ( open("/etc/passwd").readlines() ) <type 'list'> >>> type ( open("/etc/passwd") ) <type 'file'>
- die feinen Unterschiede:
- open( ... ).read(): erhalte die Datei als String
- open( ... ).readlines(): erhalte die Datei als Liste von Strings
- open( ... )(): erhalte ein Dateiobjekt
- gib das Objekt unmittelbar mit print aus (ersetze type durch print);
entspricht die Ausgabe deiner Erwartung
Schreiben
- aus Symmetrie entspricht die Ausgabe von read der Eingabe von write bzw. der von readlines der von writelines
- mittels des Ausgabeoperators >> und der String Formatierung lässt sich die Ausgabe einfach anpassen
file=open("Ausgabe.txt","w") a=1 print >> file, "%d Meine Ausgabe" % a ... file.close()
- kopiere die Datei "/etc/passwd" in dein home unter einem neuen Namen
- verwende dazu read und write
- verwende dazu readlines und writelines
- eine klassische Aufgabe für die Library shutil
- sowohl readline() aus auch readlines() berücksichtigen das plattformabhängige Zeilenendzeichen
- um den Dateizeiger mittels seek zu setzen, kann neben dem obligatorischen Offset auch die relative Position angeben, wobei where drei Werte annehmen kann:
- 0: Offset bezogen auf den Dateianfang
- 1: Offset bezogen auf die aktuelle Dateizeigerposition
- 2: Offset bezogen auf das Dateiende
- der Zustand der Datei ist in Attributen hinterlegt
Attribut Beschreibung file.closed 0 falls die Datei geöffnet ist , 2 falls nicht file.mode Modus, indem die Datei geöffnet wurde file.name Name der Datei
Standard Input, Output und Error
- die drei Standard Dateiobjekte besitzen die bekannten Integers als file descriptoren
>>> import sys >>> sys.stdin.fileno() 0 >>> sys.stdout.fileno() 1 >>> sys.stderr.fileno() 2
- das Umleiten von sys.stdout ist dadurch schnell implementiert
>>> sys.stdout= open("/home/grimm/test3","w") >>> print 1,2,3
- mit den Methoden ist es einfach möglich eine Zeile einzulesen
import sys def gets(): text= "" while 1: c= sys.stdin.read(1) text += c if c == '\n': break return text ret=gets() print "Ausgabe: ",ret,
Die gleiche Funktionalität bieten die built in Funktion raw_input und inputan.
- während raw_input die Eingabe als String interpretiert
s=raw_input("Gib irgend etwas ein: " )
- evaluiert input die Eingabe
z=input("Gib eine Zahl ein: " )
print Anweisung
- print schreibt auf sys.stdout
- print erwartet die Argumente als kommaseparierte Liste
- für jedes Argument wird die interne Funktion str() aufgerufen und ein Leerzeichen eingefügt
- die print Ausgabe wird durch ein Zeilenendzeichen abgeschlossen, sofern kein Komma an die print Anweisung angehängt wird
>>> int=1 >>> float=3.3 >>> string="test" >>> print "die Werte :" ,int,float,string die Werte : 1 3.3 test
String Formatierung
- ähnlich zur C sprintf Funktion kann der auszugebende String formatiert werden
import sys def printf(format,*args): sys.stdout.write(format % args)
- der Modulo Operator s % derzeugt einen formatierten String, mit:
- s: Formatstring mit eingebetteten Konvertierungszielen, die mit % beginnen
- d: ein Tupel von Objekten oder ein Dictionary
>>> exclamation="Ni" >>> print "The knights who says %s!" % exclamation The knights who says Ni!
- die String Konvertierer
Charakter Bedeutung s String oder jedes andere Objekt r s benutze aber repr() statt str() c Zeichen d,i Integer u Unsigned Integer o Oktal x,X Hexadezimal in Klein- oder Großbuchstaben e,E Floating Point Exponent mit kleinem oder großem e f Floating Point Dezimal g,G Float Point Dezimal oder Exponent mit kleinem oder großem e % Literal % - die allgemeine Form eines Konvertierobjekts: %[(name)][flags][widht][.precision]Charakter, mit
- name: Schlüssel eines Dictionaries
- flags:
- -: Linksausrichtung
- +: + Zeichen soll ausgegeben werden
- 0: Whitespace als Füllzeichen
- width: minimale Feldbreite
- precision:
- maximale Anzahl an Zeichen eines Strings
- Nachkommastellen einer Floating Point Zahl
- mininale Stellenzahl einer Integer
- die Anzahl der Objekte auf der rechten mit der linke Seite von % müssen übereinstimmen und ein angegebener Schlüssel muß auflösbar sein
Beispiele
- die einzelnen Optionen
>>> a=42 >>> b=13.142783 >>> c="hello" >>> d={"x":13,"y":1.54321,"z":"world"} >>> e= 562894829394939070L >>> print "a is %d" % a a is 42 >>> print "%10d %f" % (a,b) 42 13.142783 >>> print "%+010d %E" % (a,b) +000000042 1.314278E+01 >>> print "%(x)-10d %(y)0.3g" % d 13 1.54 >>> print "%0.4s %s" % (c,d["z"]) hell world >>> print "e= %d" % e e= 562894829394939070
- Stringformatierung und triple-quoted strings sind ein einfaches Mittel um Textbausteinchen erstellen zu lassen
examen=""" \ Hallo %(Vorname)s %(Nachname)s. Sie haben %(Punkte)d von %(Gesamtpunkte)d Punkten erreicht. Das entspricht der Note %(Note)s. Mit freundlichen Grüßen %(Autor)s. """ print examen %{ "Vorname": "Herbert", "Nachname": "Mustermann", "Punkte": 50, "Gesamtpunkte":130, "Note":"mangelhaft", "Autor":"Rainer Grimm"}
ergibt die Ausgabe
Hallo Herbert Mustermann. Sie haben 50 von 130 Punkten erreicht. Das entspricht der Note mangelhaft. Mit freundlichen Grüßen Rainer Grimm.
- gib /etc/passwd mit Hilfe von print und Formatstrings in einer übersichtlicheren Form aus
- die String Funktion split() hilft dir einen String in Komponenten zu splitten
>>> purifyPasswd( "%10s %2s %6s %6s %25s %25s %15s" ) root x 0 0 root / /bin/tcsh bin x 1 1 bin /bin /bin/bash daemon x 2 2 Daemon /sbin /bin/bash lp x 4 7 Printing daemon /var/spool/lpd /bin/bash mail x 8 12 Mailer daemon /var/spool/clientmqueue /bin/false games x 12 100 Games account /var/games /bin/bash wwwrun x 30 8 WWW daemon apache /var/lib/wwwrun /bin/false ftp x 40 49 FTP account /srv/ftp /bin/bash nobody x 65534 65533 nobody /var/lib/nobody /bin/bash irc x 39 65534 IRC daemon /usr/lib/ircd /bin/bash at x 25 25 Batch jobs daemon /var/spool/atjobs /bin/bash postfix x 51 51 Postfix Daemon /var/spool/postfix /bin/false man x 13 62 Manual pages viewer /var/cache/man /bin/bash news x 9 13 News system /etc/news /bin/bash uucp x 10 14 Unix-to-Unix CoPy system /etc/uucp /bin/bash ldap x 76 70 User for OpenLDAP /var/lib/ldap /bin/bash pop x 67 100 POP admin /var/lib/pop /bin/false
Weiterlesen...