Filer När ett program behöver spara data för senare användning måste dessa data antingen sparas i en databas eller skrivas på en sekundärminnesfil Sådan skrivning på fil är inte mer komplicerad än att skriva till skärmen (print (...)) utom för att få tag i respektive släppa taget om filen. Man kopplar filen till programmet och öppnar den antingen för läsning eller skrivning (eller möjligen både och) och i fallet med skrivning kan man välja att kasta all gammal data eller att lägga till i slutet av (den redan existerande) filen. Man kan använda vanliga print och input och starta programmet med t.ex. python3 prog.py < d.d > r.r Då hämtas all inmatning från filen d.d om den finns, annars klagar OS:et All utmatning sker till r.r. Finns inte r.r skapas den. DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 1 / 19
Filer... En fil är en strukturerad typ där alla poster är av samma typ. I Python är filer antingen textfiler eller binära filer. Vi kommer (nästan) bara titta på textfiler. Python betraktar all inmatning till ett program och all utmatning från ett program som filhantering men man har låtit det implicit vara så att om ingen fil anges så sker all läsning från filen sys.stdin och all skrivning till sys.stdout Om man inte ändrar något då Python startar ett program så representerar sys.stdin tangentbordet medan sys.stdout representerar skärmen. Det finns en tredje standardfil sys.stderr dit alla felutskrifter dirigeras. Vanligtvis är det samma som sys.stdout men man kan dirigera om alla tre. Man öppnar en fil med f = open(filnamn, mod) där filnamn är namnet på filen på sekundärminnet inklusive sökvägen och mod anger för vad man öppnar den (skrivning, läsning, både och, binär eller text,.... f är variabeln som används för att referera till filen i programmet. DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 2 / 19
Filer... mod innebär r öppna för läsning (standard) w öppna för skrivning (tömmer existerande fil) a öppna för skrivning (lägg till i slutet) b anger att filens innehåll ska tolkas som binära data t text-mod (standard) + öppna filen både för läsning och skrivning U universellt radbrott (finns med för bakåtkompatibilitet) använd inte! DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 3 / 19
Filer... läsning Det vanligaste är att man öppnar en fil för läsning eller skrivning och att man använder antingen r, w eller a och att man använder textfiler. När man läser från en fil finns ett stort antal metoder. Jag använder f som beteckning för en öppnad textfil, färdig för läsning, kanske öppnad med f = open( kund.txt ). s = f.read(25) innebär att 25 byte läses från filen och lagras som en textsträng i variabeln s Skulle man utelämna antalet byte eller skicka med ett negativt värde så kommer s att hålla hela filinnehållet. Det spelar ingen roll om det finns minne nog, Python försöker läsa in hela filen som en enda lång textsträng. Därför finns även andra metoder DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 4 / 19
Filer... läsning s = f.readline() läser en rad från filen och lustigt nog behålls även radbrottet så om man inte vill ha det får man ta bort det. Man ska i så fall använda en metod som inte ställer till det om sista raden i filen inte avslutas med radbrott, t.ex.: s = s.rstrip( \n ) s = f.readlines() läser in hela filen som en lista med rader, t.ex. [ Första raden\n, Andra raden\n ] Vill man vara säker på att inte ställa till det kan man ange ett tröskelvärde, s = f.readlines(1024) läser in rader tills man nått 1024 byte och sedan fortsätter tills raden som höll på att läsas då tröskelvärdet nåddes är komplett. Man läser alltså in hela rader. Stannar inte mitt i en rad. Sedan man gjort något vettigt med det inlästa kan man fortsätta i en loop tills hela filen bearbetats. Ytterligare möjlighet: for line in f: print(line, end= ) Skriver ut filens alla rader (obs att newline avslutar raderna, varav end= ) DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 5 / 19
Filer... skrivning För att skriva till en fil har man (nästan) bara ett alternativ: f.write(teckensträng) Skriver teckensträngen på filen. Observera! att man bara kan skriva tecken eller teckensträngar till normala filer. Det betyder att allt måste konverteras till teckensträngar om man inte använder binär mod. Det betyder också att man, om man skriver hela datastrukturer på en fil, måste hålla reda själv vad för typ av data man man egentligen skrivit på filen och konvertera tillbaka då man läser in filens innehåll till ett program. DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 6 / 19
Filer... skrivning Om man t.ex. skriver med f.write(str([ hej, du, glade ])) så kan man inte läsa tillbaka med x = list(f.read()) eftersom man då inte får [ hej, du, glade ] till resultat utan [ [, " ", h, e, j, " ",,,, " ", d, u, " ",,,, " ", g, l, a, d, e, " ", ] ], d.v.s. alla tecken i teckensträngen "[ hej, du, glade ]" som enskilda listelement Vid varje skrivning med f.write() får man reda på hur många byte som skrevs. DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 7 / 19
Filer... skrivning, pickle Räddningen heter pickle, en modul som konverterar i stort sett vad som helst (i Pythonväg) till en binär representation, som kan lagras på fil, läsas in till ett program och återskapas. >>> import pickle >>> pickle.dump([ hej, du, glade ], f) >>> x = pickle.load(f) >>> x [ hej, du, glade ] DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 8 / 19
Filer... Man kan naturligtvis lagra listans element, ett per rad: >>> x = [ hej, du, glade ] >>> f = open( dump, w ) >>> for i in x: f.write(i + "\n") 4 3 6 >>> f.close() och sedan läsa in rad för rad och återskapa listan >>> f = open( dump ) >>> L = [] >>> for x in f: L.append(x.rstrip("\n")) >>> L [ hej, du, glade ] DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 9 / 19
Filer... Filer kan vara både persistenta och temporära. För att skapa temporära filer importerar man biblioteket tempfile. Sådana temporära filer kan man använda som mellanlandning då man bearbetar en persistent fils innehåll för att sedan skriva tillbaka det på ursprungsfilen. >>> from tempfile import TemporaryFile >>> g = TemporaryFile() >>> g.open() >>> for x in [ hej, du, glade ]: pickle.dump(x, g) >>> g.seek(0) >>> Q = [] >>> while True: try: Q.append(pickle.load(g).rstrip("\n")) except: break >>> Q [ hej, du, glade ] >>> g.close() >>> DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 10 / 19
Filer... exempel, skriva till fil Skriva heltal till en fil (ett tal per rad) intfile = open("integerfile", w ) print( Mata in tal, negativt tal avslutar inmatningen ) count = 1 n = int(input( tal + str(count) + : )) while n >= 0: intfile.write(str(n) + \n ) count += 1 n = int(input( tal + str(count) + : )) print( Lagrade, count - 1, tal i filen, intfile.name) intfile.close() DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 11 / 19
Filer... exempel, läsa från fil Läsa heltal från textfil (ett tal per rad) filnamn = input( Filnamn? : ) f = open(filnamn) sum = 0 for i in f: sum += int(i) print( Summan =, sum) f.close() DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 12 / 19
Filer... exempel, skriva till fil Skriva heltal till en fil (ett tal per rad) from pickle import dump intfile = open("integerbinfile", wb ) print( Mata in tal, negativt tal avslutar inmatningen ) count = 1 n = int(input( tal + str(count) + : )) while n >= 0: dump(n, intfile) count += 1 n = int(input( tal + str(count) + : )) print( Lagrade, count - 1, tal i filen, intfile.name) intfile.close() DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 13 / 19
Filer... exempel, läsa från fil Läsa heltal från binärfil (lagrat med pickle) from pickle import load filnamn = integerbinfile f = open(filnamn, rb ) sum = 0 while True: try: sum += load(f) except: break print( Summan =, sum) f.close() DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 14 / 19
Filer... filtrera fil Filtrera bort rader som bara är kommentarer från en Python källkodsfil from tempfile import TemporaryFile filnamn = input( Fil att filtrera: ) f = None try: f = open(filnamn, r ) except: print( Finns ingen fil med namnet, filnamn) else: tmp = TemporaryFile(mode= w+ ) for rad in f: pos, radl = 0, list(rad) while radl[pos] in [, \t ]: pos += 1 if radl[pos]!= # : tmp.write(rad) f.close() f = open(filnamn, w ) tmp.seek(0) for rad in tmp: f.write(rad) f.close() tmp.close() DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 15 / 19
Filer... filtrera fil Filtrera bort rader som bara är kommentarer från en Python källkodsfil med hjälp av Pythons reguljära uttryck import re, tempfile matchstr = r ^\s*\# p = re.compile(matchstr) filnamn = input( Fil att filtrera: ) try: f = open(filnamn, r ) except: print( Finns ingen fil med namnet, filnamn) else: tmp = tempfile.temporaryfile(mode= w+ ) for rad in f: pos = 0 if not p.search(rad): tmp.write(rad) f.close() f = open(filnamn, w ) tmp.seek(0) for rad in tmp: f.write(rad) f.close() tmp.close() DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 16 / 19
Filer... filtrera fil Eller matcha mönstret mot hela rader: import re, tempfile matchstr = r ^\s*\#.*$ p = re.compile(matchstr) filnamn = input( Fil att filtrera: ) try: f = open(filnamn, r ) except: print( Finns ingen fil med namnet, filnamn) else: tmp = tempfile.temporaryfile(mode= w+ ) for rad in f: pos = 0 if not p.match(rad): tmp.write(rad) f.close() f = open(filnamn, w ) tmp.seek(0) for rad in tmp: f.write(rad) f.close() tmp.close() DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 17 / 19
Filer... filtrera fil Eller skriva ut alla matchande rader import re matchstr = r ^\s*\#.*$ p = re.compile(matchstr) filnamn = input( Fil att filtrera: ) try: f = open(filnamn, r ) except: print( Finns ingen fil med namnet, filnamn) else: for rad in f: pos = 0 if p.match(rad): print(rad, end= ) f.close() DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 18 / 19
Reguljära uttryck i Python Reguljära uttryck är effektiva för att hitta matchningar eller utföra sökningar men krångliga att förstå. Naturligtvis finns omfattande hjälp, dels på http://docs.python.org/py3k/library/re.html dels om man söker på regular expression python på webben dels kan man installera programmet Kodos genom att använda Ubuntus programcentral (skriv kodos i sökrutan) genom att ladda ner programmet från http://sourceforge.net/projects/kodos/files/kodos/2.4.9/kodos- 2.4.9.zip/download programmet har omfattande hjälpfunktioner DA2001 (Föreläsning 16) Datalogi 1 Hösten 2013 19 / 19