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.







