Textové a binární soubory otevřené pro čtení/zápis jsou ve skutečnosti pouze dva z mnoha různých objektů, ke kterým je možno přistupovat podobným způsobem. Tyto objekty přitom dokonce ani nemusí „fyzicky“ existovat v souborovém systému – úplně stačí, aby nějaký objekt v paměti poskytoval odpovídající programátorské rozhraní (API).
Obecně se objektům umožňujícím čtení a zápis dat z/do „sebe“ říká proudy (streams).
Na samém počátku všech proudových tříd stojí jejich nejzákladnější ABC-třída IOBase. Do jejího „veřejného“ API patří tyto metody:
close
,closed
,fileno
,flush
,isatty
,read
,readable
,readinto
,readline
,readlines
,seek
,seekable
,tell
,truncate
,write
,writeable
,writelines
read()
, readinto()
a write()
v jejím rámci deklarovány (či přímo implementovány) nejsou, protože jejich otisky jsou různé pro každou ze tří dalších tříd, které z IOBase dědí.
Samotnou IOBase v programech použít dost dobře nemůžete, ale z její „neveřejné“ části API je vidět, že:
__enter__
, __exit__
– její instance je možno používat uvnitř kontextu with;
__iter__
, __next__
– přes otevřené proudy je možno iterovat.
Ze základní ABC-třídy IOBase dědí následující tři ABC-třídy specializované na konkrétní typ proudů:
ABC-třída | metody navíc oproti IOBase | použití |
---|---|---|
RawIOBase | read , readall , readinto , write |
nízkoúrovňový přístup k vlastnímu „železu“ (například) |
BufferedIOBase | detach , read , readinto , read1 , write |
optimalizovaný přístup k binárním proudům |
TextIOBase | detach , encoding , errors , newlines , read , readline , write |
přístup k textovým proudům |
Tyto tři třídy také ještě nejsou určeny k přímému použití v programech.
Z dříve uvedených ABC-tříd jsou pak odvozeny třídy, které už je možné používat pro programovou práci s proudy. Aniž bychom zabíhali do přílišných detailů, jedná se především o třídy pro práci se:
Nejběžnější způsob vytvoření „fyzického“ proudu je pomocí vestavěné funkce open()
:
typ proudu | způsob otevření |
---|---|
textový | |
binární | |
raw | |
Přitom:
\n
a čtené sekvence bajtů jsou překládány na znaky podle zvoleného kódování.
locale.getpreferredencoding(False)
(a skutečně tam nedávejte True, to by způsobilo zavolání metody setlocale()
).
Proud vytvořený pomocí funkce open() můžete buď „po staru“ přiřadit do nějaké proměnné a odtud s ním pracovat, nebo „po novu“ radši použít uvnitř kontextu with.
Proudy v paměti vytvoříte pomocí následujících konstruktorů:
typ proudu | způsob otevření |
---|---|
textový | |
binární | |
Z hlediska práce s nimi se tyto objekty jinak tváří prakticky úplně stejně jako proudy „fyzické“.
Zdůrazněmež pro jistotu ještě jednou základní rozdíly mezi zpracováváním textových a binárních souborů (proudů):
\n
uvnitř pythoních programů.
Funkce open() je ve své plné síle mnohem mocnější, než se na první pohled zdá:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
S většinou jsme se již setkali, zde je význam zbývajících:
errors
– u textových proudů umožňuje určit způsob reakce na chyby při (de)kódování;
newline
– u textových proudů umožňuje přenastavit automatický překlad konců řádek na jiný;
closefd
– pro soubor otevřený nikoli pomocí jména, ale přímo pomocí popisovače souboru umožňuje ponechat popisovač otevřený i po zavření souboru;
opener
– umožňuje použít vlastní způsob otevření referencovaného souboru.
Pro pořádek ještě přehled možných nastavení módu pro práci se soubory:
Textové a binární soubory nejsou jediným místem, kde se v Python'u setkáme s objekty, které se chovají jako soubory (ať už „skutečné“ nebo paměťové). Mezi další patří například:
urllib.request.urlopen('ADRESA')
jako binární proudy (s několik dalšími vlastnostmi navíc);
gzip.open('SOUBOR.gz', mode='wb')
(a podobně též i pro bz2, lzma a zipfile, vše většinou až od verze Python'u 3.3);