Linux E X P R E S

Facebook

Python 3 (8): čítanie, zápis a manipulácia so súbormi

python.png

So seriálom sa dostávame k manipulácií so súbormi a ukážeme si, ako pomocou programovacieho jazyka Python súbory a priečinky čítať, vytvárať, meniť, kopírovať, premiestňovať či mazať.


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. 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.

Diskuze (3) Nahoru