Skip to content

Commit 0fea66f

Browse files
committed
Reorganize the Files lesson for the Brno beginners' course
The original lesson goes through some detours in an attempt to cover all the bases and explain things from first principles. That makes it unnecessarily hard to teach, and learn. Avoid mentioning try/finally and file.write().
1 parent ee483da commit 0fea66f

3 files changed

Lines changed: 174 additions & 1 deletion

File tree

lessons/fast-track/files/index.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# Soubory
2+
3+
Dnes se podíváme na to, jak v Pythonu číst z
4+
(a pak i zapisovat do) souborů.
5+
6+
Vytvoř si v editoru soubor `basnicka.txt` a napiš do něj libovolnou básničku.
7+
Soubor ulož.
8+
9+
> [note]
10+
> Na uložení souboru s básničkou doporučuji použít
11+
> stejný editor, jaký používáš na Pythonní programy.
12+
>
13+
> Používáš-li jiný editor než Atom, dej si při ukládání pozor na kódování:
14+
> * Nabízí-li ti editor při ukládání výběr kódování, vyber UTF-8.
15+
> * Je-li k dispozici kódování „UTF-8 bez BOM”, použij to.
16+
> * Pokud musíš použít Notepad, který výše uvedené možnosti nemá, pak v kódu
17+
> níže použij místo `'utf-8'` nestandardní `'utf-8-sig'`.
18+
>
19+
> Ono [`utf-8`] je název standardního kódování.
20+
> Zajišťuje, že se případné emoji nebo znaky s diakritikou do souboru uloží
21+
> tak, aby se daly přečíst i na jiném počítači či operačním systému.
22+
> 🎉
23+
24+
[`utf-8`]: https://en.wikipedia.org/wiki/UTF-8
25+
26+
Potom napiš tento program:
27+
28+
```python
29+
soubor = open('basnicka.txt', encoding='utf-8')
30+
obsah = soubor.read()
31+
soubor.close()
32+
33+
print(obsah)
34+
```
35+
a spusť ho z adresáře, ve kterém je
36+
`basnicka.txt` (jinými slovy, aktuální adresář musí být ten, který
37+
obsahuje soubor s básničkou).
38+
39+
Obsah souboru se vypíše!
40+
41+
Co se tu děje?
42+
Tak jako `int()` vrací čísla a `input()` řetězce, funkce
43+
`open()` vrací hodnotu, která představuje *otevřený soubor*.
44+
Tahle hodnota má vlastní metody.
45+
Tady používáme metodu `read()`, která
46+
najednou přečte celý obsah souboru a vrátí ho jako řetězec.
47+
Nakonec metoda `close()` otevřený soubor zase zavře.
48+
49+
50+
## Automatické zavírání souborů
51+
52+
Soubory se dají přirovnat k ledničce: abys něco
53+
mohl{{a}} z ledničky vzít, nebo dát dovnitř, musíš
54+
ji předtím otevřít a potom zavřít.
55+
Bez zavření to sice na první pohled funguje taky,
56+
ale pravděpodobně potom brzo něco zplesniví.
57+
58+
Stejně tak je docela důležité soubor zavřít po tom,
59+
co s ním přestaneš pracovat.
60+
Bez zavření to na první pohled funguje, ale složitější programy se můžou dostat
61+
do problémů.
62+
Operační systémy mají limity na počet
63+
současně otevřených souborů, které se nezavíráním
64+
dají snadno překročit.
65+
Na Windows navíc nemůžeš soubor, který je stále
66+
otevřený, otevřít znovu.
67+
68+
Na korektní zavření souboru ale programátoři často zapomenou.
69+
Proto Python poskytuje příkaz `with`, který soubory zavírá automaticky.
70+
Používá se takhle:
71+
72+
```python
73+
with open('basnicka.txt', encoding='utf-8') as soubor:
74+
obsah = soubor.read()
75+
76+
print(obsah)
77+
```
78+
79+
Příkaz `with` vezme otevřený soubor (který vrací funkce `open`)
80+
a přiřadí ho do proměnné `soubor`.
81+
Pak následuje odsazený blok kódu, kde se souborem můžeš pracovat – v tomhle
82+
případě pomocí metody `read` přečíst obsah jako řetězec.
83+
Když se Python dostane na konec odsazeného bloku, soubor automaticky zavře.
84+
85+
V naprosté většině případů je pro otevírání souborů nejlepší použít `with`.
86+
87+
88+
## Iterace nad soubory
89+
90+
Otevřené soubory se, jako např. řetězce či `range`,
91+
dají použít s příkazem `for`.
92+
Tak jako `for i in range` poskytuje za sebou jdoucí čísla a `for c in 'abcd'`
93+
poskytuje jednotlivé znaky řetězce, `for radek in soubor` bude do proměnné
94+
`radek` dávat jednotlivé řádky čtené ze souboru.
95+
96+
Například můžeš básničku odsadit,
97+
aby se vyjímala v textu:
98+
99+
```python
100+
print('Slyšela jsem tuto básničku:')
101+
print()
102+
103+
with open('basnicka.txt', encoding='utf-8') as soubor:
104+
for radek in soubor:
105+
print(' ' + radek)
106+
107+
print()
108+
print('Jak se ti líbí?')
109+
```
110+
111+
112+
Když to zkusíš, zjistíš, že trochu nesedí
113+
řádkování. Zkusíš vysvětlit, proč tomu tak je?
114+
115+
{% filter solution %}
116+
Každý řádek končí znakem nového řádku, `'\n'`,
117+
který možná znáš ze [sekce o řetězcích](../str/).
118+
Při procházení souboru Python tento znak nechává na konci řetězce `radek` ¹.
119+
Funkce `print` pak přidá další nový řádek, protože ta na konci
120+
výpisu vždycky odřádkovává – pokud nedostane argument `end=''`.
121+
122+
---
123+
124+
¹ Proč to dělá? Kdyby `'\n'` na konci řádků nebylo,
125+
nedalo by se např. dobře rozlišit, jestli poslední řádek
126+
končí na `'\n'`
127+
128+
{% endfilter %}
129+
130+
Ideální způsob, jak odřádkování spravit, je odstranit z konce řetězce
131+
bílé znaky (mezery a nové řádky) pomocí metody `rstrip`:
132+
133+
134+
```python
135+
print('Slyšela jsem tuto básničku:')
136+
print()
137+
138+
with open('basnicka.txt', encoding='utf-8') as soubor:
139+
for radek in soubor:
140+
radek = radek.rstrip()
141+
print(' ' + radek)
142+
143+
print()
144+
print('Jak se ti líbí?')
145+
```
146+
147+
148+
## Psaní souborů
149+
150+
> [warning] Pozor!
151+
> Pro Python není problém smazat obsah jakéhokoli souboru.
152+
> Psaní do souborů si zkoušej v adresáři, ve kterém nemáš uložené
153+
> důležité informace!
154+
155+
Soubory se v Pythonu dají i zapisovat.
156+
Pro zápis soubor otevři s pojmenovaným
157+
argumentem `mode='w'` (z angl. *mode*, mód a *write*, psát).
158+
159+
Pokud soubor už existuje, otevřením s `mode='w'` se veškerý jeho obsah smaže.
160+
Po zavření tak v souboru bude jen to, co do něj ve svém programu zapíšeš.
161+
162+
Informace pak do souboru zapiš známou funkcí `print`,
163+
a to s pojmenovaným argumentem `file`:
164+
165+
```python
166+
with open('druha-basnicka.txt', mode='w', encoding='utf-8') as soubor:
167+
print('Naše staré hodiny', file=soubor)
168+
print('Bijí', 2+2, 'hodiny', file=soubor)
169+
```

lessons/fast-track/files/info.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
title: Soubory
2+
style: md
3+
attribution: Pro PyLadies Brno napsal Petr Viktorin, 2014-2018.
4+
license: cc-by-sa-40

runs/2018/pyladies-brno-podzim/info.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ plan:
107107
date: 2018-11-07
108108
materials:
109109
- lesson: git/collaboration
110-
- lesson: beginners/files
110+
- lesson: fast-track/files
111111
- title: Gitový tahák
112112
url: https://pyvec.github.io/cheatsheets/basic-git/basic-git-cs.pdf
113113
type: cheatsheet

0 commit comments

Comments
 (0)