Otvorenie súboru
Pre otvorenie súboru sa v Pythone používa funkcia open()
, ktorá má niekoľko parametrov, z ktorých názov – cesta ku súboru je samozrejme parametrom povinným. S voliteľných parametrov tejto funkcie spomeniem len mode
– určuje v akom režime (čítanie, zápis atp.) je súbor otvorený, encoding
– kódovanie súboru alebo newline
– spôsob zakončenia riadku.
Základné použitie tejto funkcie vyzerá takto:
f = open("file.name")
Premenná f teraz obsahuje otvorený súbor – objekt typu _io.TextIOWrapper
, s ktorým je možné manipulovať až do jeho zavretia použitím metódy close()
:
f.close()
Lepší spôsob otvárania súborov
Existuje ďalší, efektívnejší spôsob ako pracovať so súborom – použitie výrazu with
:
with open("file.name") as f: pass
Použite with
je výhodnejšie z viacerých dôvodov. So súborom pracujete vrámci bloku with
, pričom po ukončení práce so súborom, čiže potom ako sú všetky príkazy v bloku vykonané, je súbor automaticky uzavretý, čo znamená, že nemusíte používať f.close()
. Ďalšími výhodami sú napríklad krajšia syntax (viď porovnanie nižšie) a lepšie spracovanie chýb. Kvôli tomu budem vo všetkých nadchádzajúcich príkladoch používať práve tento spôsob.
Porovnanie syntaxe s a bez použitia with.
Čítanie súboru
Funkcia open()
pri nedefinovaní režimu otvorenia súboru automaticky použije režim iba na čítanie, takže nieje potrebné používať: open("file.name", mode="r")
. Dáta zo súboru vieme čítať rôznymi spôsobmi. Pre uloženie obsahu súboru do jedného reťazca môžeme použiť metódu read()
, metóda readline()
nám umožňuje čítať riadok po riadku a readlines()
zabalí obsah súboru do zoznamu obsahujúce reťazce rozdelené po riadkoch. Poďme si teda názorne ukázať, ako to funguje. Pre ukážku použijem súbor text.txt s nasledujúcim obsahom:
Prvý riadok súboru je o ničom. Druhý je už trošku lepší. Tretí riadok je prázdny.
read()
Myslím, že nejaké vysvetľovanie už nieje potrebné, a tak rovno príklad z interpretera:
>>> with open("text.txt") as f: ... text = f.read() ... print(text) ... Prvý riadok súboru je o ničom. Druhý je už trošku lepší. Tretí riadok je prázdny. >>> text # toto je podoba reťazca v nespracovanej podobe pomocou print() 'Prvý riadok súboru je o ničom.\nDruhý je už trošku lepší.\n\nTretí riadok je prázdny.'
readline()
>>> with open("text.txt") as f: ... for i in range(2): ... line = f.readline() ... line = line.replace(" ", "_") ... print(line, end="") ... Prvý_riadok_súboru_je_o_ničom. Druhý_je_už_trošku_lepší.
readlines()
>>> with open("text.txt") as f: ... lines = f.readlines() ... print(lines) ... ['Prvý riadok súboru je o ničom.\n', 'Druhý je už trošku lepší.\n', '\n', 'Tretí riadok je prázdny.']
Vďaka skutočnosti spomenutej vyššie je možné obsah súboru po riadkoch jednoducho uložiť aj prevedením objektu f
na zoznam, jedná sa totiž o rovnaký proces:
>>> with open("text.txt") as f: ... lines = list(f) ... print(lines) ... ['Prvý riadok súboru je o ničom.\n', 'Druhý je už trošku lepší.\n', '\n', 'Tretí riadok je prázdny.']
Zápis do súboru
Pre zápis do súboru môžeme pri otvorení súboru použiť viacero režimov, a to napríklad "r+" na čítanie a zápis, "w" na zápis, s tým, že pôvodný súbor bude prepísaný alebo "a" na zápis na koniec súboru (append). Pre zapisovanie potom máme dostupné metódy write() a writelines()
.
Pri otvorení súboru v režime "r+", čiže čítanie a zapisovanie, sa kurzor v súbore nachádza pred prvým znakom. To znamená, že pokiaľ začneme zapisovať, súbor budeme postupne prepisovať. Po použití read()
sa kurzor posunie na koniec súboru. Vysvetlenie na príklade z interpretera pri použití rovnakého textového dokumentu text.txt:
>>> with open("text.txt", "r+") as f: ... f.write("Piaty") # prepíše začiatok súboru a kurzor ostane posunutý ... print(f.read()) # prečíta zbytok súboru ... f.write(" Posledné slovné spojenie.") # reťazec zapíše na koniec súboru ... 5 riadok súboru je o ničom. Druhý je už trošku lepší. Tretí riadok je prázdny. 26
text.txt bude potom vyzerať takto:
Piaty riadok súboru je o ničom. Druhý je už trošku lepší. Tretí riadok je prázdny. Posledné slovné spojenie.
Pokiaľ súbor neexistuje a chceme ho vytvoriť, musíme použiť režim zapisovania:
>>> with open("test.txt", "r+") as f: # funguje iba ak súbor existuje ... f.write("slovné spojenie") ... Traceback (most recent call last): File "<stdin>", line 1, in <module> FileNotFoundError: [Errno 2] No such file or directory: 'test.txt' >>> with open("test.txt", "w") as f: ... f.write("slovné spojenie") ... 15
Práca so súbormi a priečinkami
Pre ďalšiu prácu so súbormi budeme využívať funkcie vstavaného Python modulu os, ktorý importujeme príkazom import os
.
Získanie zoznamu súborov a priečinkov v aktuálnom priečinku:
>>> os.listdir() ['text.txt.bak', 'nowith.py', 'porovnanie_with-vs-nowith.png', 'text.txt', '.~lock.Python08.odt#', 'Python08.odt', 'with.py']
Zmazanie súboru:
>>> os.remove("text.txt.bak") >>> os.listdir() ['nowith.py', 'porovnanie_with-vs-nowith.png', 'text.txt', '.~lock.Python08.odt#', 'Python08.odt', 'with.py']
Vytvorenie nového priečinka:
>>> os.mkdir("test") >>> os.listdir() ['nowith.py', 'porovnanie_with-vs-nowith.png', 'test', 'text.txt', '.~lock.Python08.odt#', 'Python08.odt', 'with.py']
Premenovanie a/alebo presunutie súboru alebo priečnika:
>>> os.rename("text.txt", "test/iný názov.txt") >>> os.listdir() ['text.txt.bak', 'nowith.py', 'porovnanie_with-vs-nowith.png', 'test', '.~lock.Python08.odt#', 'Python08.odt', 'with.py']
Zmena aktuálneho priečinka:
>>> os.chdir("test") >>> os.listdir() ['iný názov.txt']
Získanie cesty k aktuálnemu priečinku:
>>> os.getcwd() '/home/user/Python/Python 08/test'
Pre kopírovanie už v module os funkcia neexistuje, ale nejakú jednoduchú si vieme napísať aj sami:
>>> def copy(src, dst): ... with open(src, "rb") as s, open(dst, "wb") as d: # b › bytes ... d.write(s.read()) ... >>> copy("text.txt.bak", "copy.txt")
Záver
Toto samozrejme nieje všetko, čo sa manipulácie so súbormi týka, avšak myslím, že som spomenul tie základné veci, ktoré sa možno niekedy zídu. Viac informácií sa dočítate v oficiálnej dokumentácii.
Do budúcej časti by som rád spracoval nejaké základy objektového programovania v Python 3. Otázky a návrhy privítam v komentároch.