přejít na obsah přejít na navigaci

Linux E X P R E S, Python 3 (8): čítanie, zápis a manipulácia so súbormi

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.

Nahoru

Odkazy

Příspěvky

Python 3 (8): čítanie, zápis a manipulácia so súbormi
Pavel Šimerda 27. 08. 2015, 17:52:16
Odpovědět  Odkaz 
Nemůžu si pomoct, ale příklad s přepisováním začátku textového souboru mi nedává vůbec žádný smysl. Sice to kupodivu opravdu zafunguje tak, jak je popsáno, ale jenom shodou několika v textu nevysvětlitelných okolností. Funguje to díky tomu, že je „Piaty“ napsáno špatně (bez čárky nad y) a tím získává v UTF-8 stejnou bajtovou délku jako „Prvý“.

Celá tato část článku má několik zásadních problémů.

1) Takto se textové soubory nepoužívají, není to prakticky vůbec užitečné.

2) Takto ukázaný program vytváří nesmyslná očekávání, že lze pomocí `open(..., "r+")` nahradit slovo jiným slovem. Přitom dokonce i v tomto případě to platí jen díky konkrétní délce slov a i ta je dosažena chybou v jednom ze slov.

3) Program pracuje s textovým souborem a přitom proplouvají na povrch vlastnosti binárních zápisů. Osobně si myslím, že jedna z hlavních výhod „trojky“ je, že se lze vyvarovat míchání binární a textové reprezentace dat. Tato ukázka jde ovšem přesně opačným směrem.

Mimochodem, článek neukazuje nejelegantnější metodu přístupu k textovým souborům, kterou je bezesporu prostá iterace otevřeného souboru, tedy kombinace `with` a `for`.
Štefan Uram Re: Python 3 (8): čítanie, zápis a manipulácia so súbormi
Štefan Uram 27. 08. 2015, 22:12:17
Odpovědět  Odkaz 
Vďaka za veľmi trefný komentár, ktorému nemôžem oponovať. Je to totiž pravda.
Týchto nezmyselností som si bohužiaľ bol vedomí už pri písaní článku, ktorý som však písal vo veľmi veľkých intervaloch kvôli nedostatku času a na rýchlo, keďže som sa chcel vyvarovať časovému sklzu, čo spôsobilo totálnu nekonzistnosť myslenia. Áno, pravda, môžem sa vlastne vyhovoriť na hocičo, čo mi napadne, no kvalitu článku tým už nezmením.
Ospravedlňovať sa zaň je asi takisto úplne bezpredmetné a jediné čo mi ostáva, je poučiť sa z tohto a v pokračovaní si dať na kvalite a využiteľnosti viac záležať aj na úkor času.
Python 3 (8): čítanie, zápis a manipulácia so súbormi
sarimak 8. 09. 2015, 15:50:00
Odpovědět  Odkaz 
Bylo by prosim mozne doplnit, ze pokud v open() nespecifikujeme kodovani, pouzije se locales a ne Unicode? Na Windows je to docela problem, cp1250 != utf-8.

Typicke pouziti s explicitne uvedenym kodovanim:

with open(filename, "rt", encoding="utf-8") as myfile:

Odpovědět

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz