import, from ... import ..., __name__, serializace objektůdata.py, postavy.py, ulozeni.py, app.pyNejlepší úvod je ukázat jejich app.py z minulé hodiny:
Kolik má tenhle soubor řádků? Tři sta? Čtyři sta? Zkus najít třídu
Drak. Kolikrát jsi musel rolovat?A teď si představ, že jich tam bude tisíc. Takhle vypadá každý program, který někdo skutečně používá. Proto se kód rozděluje do souborů.
Klíčová věta hodiny:
Dnes nepřidáme ani jednu novou funkci. Program bude po hodině dělat přesně to samé. Ale bude se v něm dát žít.
To je důležité říct nahlas — děti jinak mají pocit, že se nic nestalo. Pojmenujte to: refaktoring = zlepšení struktury bez změny chování.
pyquest/
├── app.py ← spouští se
├── data.py ← místa, předměty, ceny
├── postavy.py ← třídy Hrdina, Prisera...
└── ulozeni.py ← načítání a ukládání
Modul je prostě soubor s Pythonem. Nic víc. Když napíšeš
postavy.py, máš modul jménempostavy.
import data # 1
st.write(data.MISTA)
from data import MISTA # 2
st.write(MISTA)
from postavy import Hrdina, Drak # 3
| Zápis | Kdy použít |
|---|---|
import data |
Je vidět, odkud věc pochází. Bezpečné. |
from data import MISTA |
Krátké, když z modulu bereš pár věcí. |
from data import * |
Nikdy. Nevidíš, co se přineslo. |
Doporučení: varianta 3 pro třídy a funkce, varianta 1 pro data.
Tohle vysvětlete, jinak budou zmatení z chyb:
Když napíšeš
import postavy, Python se podívá: 1. do složky, kde je spouštěný soubor, 2. do nainstalovaných balíčků.Proto musí být
postavy.pyve stejné složce jakoapp.py.
Chyba ModuleNotFoundError: No module named 'postavy' má skoro vždy
jednu ze tří příčin: špatná složka, překlep v názvu, nebo koncovka .py v importu.
# postavy.py
from ulozeni import nacti # ← ulozeni importuje postavy
# ulozeni.py
from postavy import Hrdina # ← postavy importuje ulozeni
Dva soubory na sebe čekají navzájem. Python to vzdá a zahlásí chybu. Pravidlo: udělej si směr. Data neví o postavách. Postavy neví o aplikaci. Aplikace ví o všech.
data.py (neimportuje nic vlastního)
↑
postavy.py (může importovat data)
↑
ulozeni.py (může importovat postavy)
↑
app.py (importuje všechno)
Nakreslete tuhle šipku na tabuli. Řeší to 90 % problémů.
Řešení, které uvidíš v každém tutoriálu:
__name__je proměnná, kterou Python nastaví sám. Když soubor spouštíš, je v ní"__main__". Když ho importuješ, je v ní jméno modulu.
Použití: jednoduché testy modulu na jeho konci.
Objekty se do JSON uložit nedají. Podívej se:
json.dumps(hrdina) # TypeError: Object of type Hrdina is not JSON serializable
JSON umí jen slovníky, seznamy, čísla, texty a
True/False/None. Objekt tam prostě nepatří. Musíš mu vysvětlit, jak se má „složit do krabice".
class Hrdina:
def to_dict(self):
"""Objekt → slovník (do souboru)."""
return {
"jmeno": self.jmeno,
"zivoty": self.zivoty,
"zlato": self.zlato,
"typ": type(self).__name__,
}
@staticmethod
def from_dict(d):
"""Slovník → objekt (ze souboru)."""
h = Hrdina(d["jmeno"])
h.zivoty = d["zivoty"]
h.zlato = d["zlato"]
return h
Analogie: „skládám nábytek do krabice a zase ho složím zpátky".
Klíč "typ" je důležitý — bez něj po načtení nepoznáš, jestli to byl
bojovník nebo kouzelník.
import modul spustí jednou a uloží do sys.modules. Opakovaný import
už nic nedělá. Proto Streamlit hot-reload někdy nezachytí změnu v modulu —
řešení je restart, případně importlib.reload.__init__.py. Do výuky pro 12–15 let bych to nedával,
ploché soubory stačí a __init__.py je od Pythonu 3.3 nepovinný (namespace packages).import je using,
ale importuje se soubor, ne namespace. Neexistuje internal/private
na úrovni modulu, jen konvence _nazev = „nesahej na to".dataclasses.asdict, pydantic, attrs.
to_dict/from_dict je ale pedagogicky nejlepší — děti vidí, co se děje.@staticmethod vs @classmethod: pro from_dict je čistší @classmethod
(pracuje s cls), ale @staticmethod je pro děti srozumitelnější.Nedělejte to najednou. Postupujte v tomto pořadí a po každém kroku spusťte aplikaci:
data.py, přidej import, spusť.postavy.py, přidej import, spusť.ulozeni.py, přidej import, spusť.app.py zůstane jen UI.Po každém kroku spusť aplikaci. Když nefunguje, víš přesně, co jsi rozbil. Když přesuneš všechno najednou a spadne to, hledáš chybu půl hodiny.
Tohle je nejcennější návyk celé hodiny.
| Chyba | Příčina | Řešení |
|---|---|---|
ModuleNotFoundError |
Soubor v jiné složce nebo překlep | Stejná složka, přesný název |
import postavy.py |
Koncovka v importu | Bez .py |
ImportError: cannot import name |
Kruhový import | Dodržet směr šipky |
NameError po přesunu |
Zapomenutý import v novém modulu | Doplnit import random apod. |
| Změna v modulu se neprojeví | Cache importů | Restartovat aplikaci |
Object is not JSON serializable |
Ukládá se objekt | Použít to_dict() |
| Po načtení je hrdina špatného typu | Chybí klíč "typ" |
Uložit a přečíst typ |
Zadání:
- Vytvoř soubor
data.pya dej do něj slovníkMISTA- Přidej do něj i
PREDMETYaCENY- V
app.pynapišimport data- Vypiš místa přes
data.MISTA- Přidej do
data.pynové místo a ověř, že se v aplikaci objeví
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–3 |
| Rozšíření | Bod 4 |
| Výzva | Bod 5 + vyzkoušet i from data import MISTA |
Očekávaný výsledek: aplikace čte data z jiného souboru.
Zadání:
- Vytvoř
nastroje.pys funkcíhod_kostkou(pocet, stran)- Přidej funkci
procenta(cast, celek)vracející text jako"75 %"- Přidej funkci
zdravi_bar(zivoty, max_zivoty)vracející"█████░░░░░"- Na konec
nastroje.pypřidejif __name__ == "__main__":s testem- Použij všechny tři funkce v aplikaci
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2 |
| Rozšíření | Bod 3 |
| Výzva | Body 4–5 |
Očekávaný výsledek: vlastní mini-knihovna, kterou lze používat kdekoli.
Zadání:
- Vytvoř
postavy.pya přesuň do něj tříduBojujici- Přesuň i
Hrdina,Bojovnik,Kouzelnik,Lupic- Přesuň příšery —
Prisera,Skret,Vlk,Drak- Nezapomeň na
import randomuvnitřpostavy.py- V aplikaci naimportuj jen to, co potřebuješ
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2 |
| Rozšíření | Body 3–4 |
| Výzva | Bod 5 + slovník POVOLANI přímo v postavy.py |
Očekávaný výsledek: app.py je najednou o dvě stě řádků kratší.
Zadání:
- Přidej třídě
Hrdinametoduto_dict()- Přidej statickou metodu
from_dict(d)- Do slovníku ulož i klíč
"typ"s názvem třídy- Vytvoř
ulozeni.pys funkcemiuloz(hrdina)anacti()- Otestuj: ulož hrdinu, restartuj aplikaci, načti ho zpět
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2 |
| Rozšíření | Body 3–4 |
| Výzva | Bod 5 + ať from_dict vrátí správné povolání podle "typ" |
Očekávaný výsledek: hrdina přežije restart aplikace i s povoláním.
streamlit run.Zadání:
- Rozděl hru na
data.py,postavy.py,ulozeni.pyaapp.py- Po každém přesunu aplikaci spusť a ověř, že funguje
- Dodrž směr importů — data neví o postavách
- V
app.pynech jen UI, žádné třídy ani data- Přidej do každého modulu docstring, co v něm je
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2 |
| Rozšíření | Body 3–4 |
| Výzva | Bod 5 + přidat nastroje.py s pomocnými funkcemi |
Očekávaný výsledek: stejná hra, čtyři přehledné soubory.
streamlit run.Vytvoř soubor
nastroje.pya přesuň do něj alespoň tři pomocné funkce, které používáš v aplikaci. Na jeho konec přidejif __name__ == "__main__":s testem každé funkce. Spusť v terminálupython nastroje.pya přines výpis (nebo screenshot).
Toto je jedna z možných variant, jak mohl úkol dopadnout. Tvoje řešení se může lišit a to je v pořádku.
Oficiální dokumentace se hodí, když si chceš ověřit, jak Python hledá moduly, co přesně dělá import nebo jak funguje __name__ == "__main__". U modulů se vyplatí dívat hlavně na názvy kapitol a krátké příklady.
| Co jsme použili | Oficiální dokumentace | Co tam najdeš |
|---|---|---|
| moduly | Modules | proč rozdělovat kód do souborů a jak moduly používat |
import |
The import statement | přesný význam různých zápisů importu |
| balíčky | Packages | jak se větší projekty skládají z více modulů |
__name__ == "__main__" |
__main__ |
kdy se soubor spouští přímo a kdy je jen importovaný |
json |
json |
ukládání slovníků, čtení JSONu a převod dat |
| Cvičení | Odkaz | Proč se hodí |
|---|---|---|
| Programování v Pythonu | umimeinformatiku.cz | Struktura programu |
| Tabulky | umimeinformatiku.cz | Data odděleně od logiky |
| Algoritmické myšlení | umimeinformatiku.cz | Rozklad problému |
| Kódování a modelování | umimeinformatiku.cz | Reprezentace dat |