Všetko, čo program uloží do premenných, zmizne, keď program skončí. Ak chceme údaje zachovať – výsledky, nastavenia, záznamy – alebo spracovať veľké množstvo údajov pripravených vopred, použijeme súbory. V tejto téme sa naučíš čítať a zapisovať textové súbory: otvoriť súbor, prečítať ho riadok po riadku, rozobrať riadky na údaje a výsledky zapísať do iného súboru.
Čo sa naučíš
- otvoriť súbor v správnom režime (
"r","w","a") a s kódovaním UTF-8, - čítať celý súbor aj po riadkoch a odstrániť znak konca riadku,
- zapisovať do súboru a pridávať na jeho koniec,
- používať blok
with, ktorý súbor spoľahlivo zatvorí, - spracovať súbor s údajmi oddelenými bodkočiarkou.
1Textový súbor
Textový súbor je postupnosť riadkov textu. Každý riadok (možno okrem posledného) končí neviditeľným znakom konca riadku \n. Program hľadá súbor podľa mena v pracovnom priečinku – zvyčajne v tom istom priečinku, v ktorom je uložený program. Súbor môže byť aj inde, potom treba uviesť cestu ("data/body.txt").
V ukážkach budeme používať tento súbor:
Súbor teploty.txt:
12.5 14.0 9.5 17.0
2Otvorenie súboru
Súbor otvoríme funkciou open. Dostane meno súboru, režim a kódovanie:
| Režim | Význam | Ak súbor neexistuje | Ak súbor existuje |
|---|---|---|---|
"r" | čítanie (predvolený) | chyba FileNotFoundError | číta sa od začiatku |
"w" | zápis | vytvorí sa nový | pôvodný obsah sa zmaže |
"a" | pridávanie na koniec | vytvorí sa nový | píše sa za pôvodný obsah |
Ak súbor na čítanie neexistuje (preklep v mene, iný priečinok), program skončí chybou:
Výstup (program skončí chybou):
Traceback (most recent call last):
File "program.py", line 1, in <module>
f = open("tepoty.txt", "r", encoding="utf-8")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'tepoty.txt'Ako takúto chybu zachytiť, sa dozvieš v téme Výnimky.
3Blok with
Otvorený súbor treba po práci zatvoriť – až vtedy sa zapisované údaje naozaj uložia na disk a súbor sa uvoľní pre iné programy. Najbezpečnejšie je použiť blok with: súbor sa zatvorí automaticky na konci bloku, aj keby v ňom nastala chyba.
Výstup:
12.5
14.0
9.5
17.0as f pomenuje otvorený súbor – cez f s ním v bloku pracujeme. Za blokom (bez odsadenia) je súbor už zatvorený. Starší spôsob bez with vyzerá takto: f = open(...), práca so súborom a nakoniec f.close() – zatvorenie sa však ľahko zabudne.
4Čítanie súboru
4.1Celý súbor naraz: read()
f.read() vráti celý obsah ako jeden reťazec (aj so znakmi \n). Hodí sa pre menšie súbory, napríklad keď chceme spočítať znaky alebo slová.
4.2Riadok po riadku: for
Najčastejšie súbor čítame cyklom for – v každom opakovaní dostaneme jeden riadok:
Výstup:
'12.5\n'
'14.0\n'
'9.5\n'
'17.0\n'Funkcia repr ukázala to, čo je inak neviditeľné: každý riadok končí znakom \n. Preto pred ďalším spracovaním riadok takmer vždy „očistíme“ metódou strip(), ktorá odstráni koniec riadku a medzery na okrajoch:
Výstup:
Priemerná teplota: 13.25 °C(float a int si s koncom riadku poradia aj samy, ale pri porovnávaní textu – riadok == "Eva" – by bez strip() podmienka nikdy neplatila.)
4.3Všetky riadky do zoznamu: readlines() a read().splitlines()
Výstup:
['12.5', '14.0', '9.5', '17.0']
Počet riadkov: 4
Najvyššia: 17.0f.readlines() vráti zoznam riadkov aj so znakmi \n; f.read().splitlines() ich vráti bez nich. Jeden riadok prečíta f.readline().
5Zápis do súboru
Na zápis otvoríme súbor v režime "w" a použijeme metódu write. Tá na rozdiel od print nepridáva koniec riadku – musíme ho napísať sami ("\n"). Do write patrí iba text, čísla treba previesť (str, f-reťazec).
Výstup:
1 x 7 = 7
2 x 7 = 14
3 x 7 = 21
4 x 7 = 28
5 x 7 = 35Do súboru sa dá zapisovať aj príkazom print s parametrom file – potom sa koniec riadku pridá sám:
Výstup:
Ahoj, svet!
Druhý riadok(Režim "r" je predvolený, preto ho pri čítaní môžeme vynechať.)
5.1Pridávanie na koniec: režim "a"
Režim "w" pôvodný obsah zmaže. Ak chceme pridávať – napríklad do denníka alebo záznamu výsledkov –, použijeme "a" (append):
Výstup:
pondelok: 12 °C
utorok: 15 °C
streda: 9 °C6Spracovanie riadkov s údajmi
Údaje v súboroch často bývajú v stĺpcoch oddelených znakom – bodkočiarkou, čiarkou alebo tabulátorom (formát CSV). Každý riadok rozdelíme metódou split a jednotlivé časti prevedieme na správny typ.
Súbor vysledky.txt:
meno;trieda;body Ema;3.A;47 Ján;3.B;38 Sofia;3.A;50 Tomáš;3.B;44
Súbor má hlavičku (prvý riadok s názvami stĺpcov) a jeden prázdny riadok – oboje treba pri spracovaní preskočiť:
Výstup:
Ema 3.A 47
Ján 3.B 38
Sofia 3.A 50
Tomáš 3.B 44
Priemer: 44.75Postup spracovania riadku si zapamätaj: strip → (preskoč prázdny) → split → prevod na čísla.
7Riešené úlohy
7.1Výsledky podľa tried do nového súboru
Zadanie: Zo súboru vysledky.txt vypočítaj priemer bodov každej triedy a výsledok zapíš do súboru triedy.txt v tvare 3.A: 48.5.
Riešenie: Body sčítavame v slovníku trieda → zoznam bodov (téma Slovníky). Potom priemery zapíšeme do nového súboru.
Výstup:
3.A: 48.5
3.B: 41.0setdefault(trieda, []) vráti zoznam pre danú triedu, a ak ešte neexistuje, najprv ho vytvorí prázdny – praktická skratka.
7.2Štatistika textového súboru
Zadanie: Spočítaj, koľko riadkov, slov a znakov má súbor.
Súbor basen.txt:
Prší, prší, len sa leje, kde ste, vtáčky, kde ste?
Výstup:
Riadkov: 2
Slov: 10
Znakov (bez koncov riadkov): 497.3Očíslovanie riadkov
Zadanie: Skopíruj súbor basen.txt do súboru cislovana.txt a pred každý riadok pridaj jeho číslo.
Výstup:
1: Prší, prší, len sa leje,
2: kde ste, vtáčky, kde ste?Riadok už obsahuje \n, preto ho za riadok nepridávame. V jednom with môžeme otvoriť aj dva súbory naraz.
8Časté chyby
- Zabudnutý
strip(): riadok obsahuje\n, takžeriadok == "Eva"neplatí ani pri riadku s menom Eva. - Režim
"w"namiesto"a": zápis zmaže všetko, čo v súbore bolo. - Chýbajúci
\npriwrite: všetko sa zapíše do jedného dlhého riadku. - Zápis čísla:
f.write(42)je chyba –writeprijíma iba text (f.write(str(42))). - Súbor sa nenašiel: skontroluj meno, príponu (
.txt) a priečinok, z ktorého sa program spúšťa. - Chýbajúce
encoding="utf-8": pokazená diakritika. - Opakované čítanie: po
read()je súbor „dočítaný“; ďalšie čítanie vráti prázdny text.
Zhrnutie
with open(meno, režim, encoding="utf-8") as f:– súbor sa na konci bloku sám zatvorí.- Režimy:
"r"čítanie,"w"zápis (zmaže obsah),"a"pridávanie na koniec. - Čítanie:
f.read()(celý text),for riadok in f(po riadkoch),f.read().splitlines()(zoznam riadkov bez\n),f.readline()(jeden riadok). - Každý riadok končí
\n– odstráň hostrip(). - Zápis:
f.write(text)(bez automatického\n) aleboprint(..., file=f). - Spracovanie údajov: strip → preskoč prázdne →
split(";")→ prevod typov.
Úlohy na precvičenie
- Zapíš do súboru čísla 1 až 100, každé na samostatný riadok, a potom zo súboru vypočítaj ich súčet.
- Zo súboru s menami (jedno na riadok) vypíš mená zoradené abecedne a zapíš ich do nového súboru.
- Zo súboru
vysledky.txtvypíš meno s najvyšším počtom bodov. - Napíš program, ktorý pri každom spustení pridá do súboru
log.txtriadok s textom zadaným z klávesnice. - Spočítaj, koľkokrát sa v textovom súbore vyskytuje každé slovo, a 5 najčastejších zapíš do súboru.