4. diel - Uloženie objektov do CSV v Pythone
V minulej lekcii, Práca s textovými súbormi v Pythone , sme si ukázali zápis do textových súborov aj ich čítanie. Aplikácia bola jednoduchá a skôr učebnicová. Urobme si teraz naozajstnú databázu užívateľov pomocou textových súborov. Ukladať budeme samozrejme objekty, čiže si program ľahko prerobíte na databázu upomienok v diári, databáze najlepších výsledkov v hre, databázu zvierat v chovnej stanici alebo na čokoľvek, čo budete potrebovať evidovať.
Formát CSV
Nebudeme vymýšľať žiadny zložitý spôsob ukladania dát do textových súborov, pretože už jeden osvedčený a štandardné existuje. Volá sa CSV (ako Comma Separated Values), teda hodnoty oddelené čiarkou, prípadne bodkočiarkou.
Poďme sa zhodnúť na tom, ako bude trieda užívateľa vyzerať. Následne
si ukážeme, ako jej inštancie do CSV uložíme. Vytvoríme si nový súbor
main.py
. Do neho si vložíme triedu Uzivatel
. U
užívateľa budeme evidovať jeho meno, vek a dátum, kedy bol registrovaný.
Konštruktor bude inštanciu inicializovať na základe týchto 3 vlastností.
Prepíšeme si metódu __str__()
tak, aby vrátila meno
používateľa. Trieda teda bude vyzerať takto:
class Uzivatel(): def __init__(self, jmeno, vek, registrovan): self.jmeno = jmeno self.vek = vek self.registrovan = registrovan def __str__(self): return self.jmeno
Poďme si ukázať, ako budú používatelia vo formáte CSV vyzerať. Každý riadok bude reprezentovať jedného používateľa. Vlastnosti užívateľa budú oddelené bodkočiarkami. Užívateľ Pavel Slavík, ktorému je 22 rokov a zaregistroval sa 21.3.2000 by vyzeral takto:
Pavel Slavík;22;21.3.2000
Na prvý pohľad vidíme, že je súbor relatívne jednoducho čitateľný,
aj keď Nezainteresovaný sa môže len domnievať, čo je číslo
22
a na čo sa viaže ono dátum.
V súbore môže byť samozrejme viac užívateľov, teda viac riadkov.
Triedu užívateľa máme, pretože však ctíme objektový návrh,
vytvoríme si aj triedu pre našu databázu. Tá bude obsahovať kolekciu
užívateľov, tvorenú zoznamom. Pridávanie užívateľov (prípadne ich
mazanie, vyhľadávanie a podobne) bude realizované metódami. Databáza bude
konečne obsahovať metódy na načítanie CSV súboru a tiež na uloženie
obsahu databázy do súboru. Meno súboru bude ďalší atribút databázy.
Pridajme si teda k projektu ďalšiu triedu Databaze
a nápis jej
kostru:
class Databaze(): uzivatele = [] def __init__(self, soubor): pass def pridejUzivatele(self, jmeno, vek, registrovan): pass def vratVsechny(self): pass def uloz(self): pass def nacti(self): pass
Poďme postupne naimplementovať jednotlivé metódy. Začnime konstruktoru.
V konstruktoru si uložíme cestu na databázový súboru:
def __init__(self, soubor): self.soubor = soubor
To bolo veľmi jednoduché a aj na ďalšie metóde nie je čo vymýšľať:
def pridejUzivatele(self, jmeno, vek, registrovan):
u = Uzivatel(jmeno, vek, registrovan)
self.uzivatele.append(u)
Metóda vratVsechny()
nám vráti všetkých užívateľov.
Podobne môžeme v budúcnosti urobiť metódy pre vyhľadávanie len
niektorých užívateľov. Užívateľa vrátime vo forme poľa:
def vratVsechny(self): return self.uzivatele
Uloženie užívateľov do CSV
Teraz sa konečne dostávame k práci s CSV súborom. Začneme
with
blokom a inštancií file Handler získanú funkcií
open()
. Vnútri proiterujeme náš zoznam užívateľov a pre
každého užívateľa vytvoríme pole stringov z jeho vlastností. Nestringové
vlastnosti musíme na string explicitne previesť. Pole potom spojíme na dlhý
string, v ktorom budú položky oddelené bodkočiarkami. Spojenie za nás
vykoná metóda join()
. Tá sa na rozdiel od metódy
split()
volá priamo na reťazci (rozdeľovača) a ako parameter
prijíma jednotlivé položky na spojenie. Pusťme sa do toho:
def uloz(self): with open(self.soubor, "w", encoding="utf-8") as f: for u in self.uzivatele: hodnoty = [u.jmeno, str(u.vek), u.registrovan.strftime("%d.%m.%Y")] radek = ";".join(hodnoty) f.write(radek + "\n")
Všimnite si, že dátum registráciu pred uložením do súboru naformátujeme na "deň.mesiac.rok".
Aplikácie
Naša aplikácia bude formulárové pomocou knižnice tkinter
.
Ak preferujete radšej PyQt,
bude pre vás vďaka jej jednoduchosti hračka ju aj pre túto knižnicu
upraviť.
Do main.py
si vložme poslednú triedu, reprezentujúci okno
aplikácie:
class Aplikace(tkinter.Frame): def __init__(self, master): super().__init__(master=master) self.master = master self.pack() self.db = Databaze("uzivatele.csv") self.master.title("Lekce4") self.tlacitkoUlozit = tkinter.Button(self.master, text="Uložit", width=40, command=self.tlacitkoUlozitClicked) self.tlacitkoUlozit.pack(fill=tkinter.X) def tlacitkoUlozitClicked(self): pass root = tkinter.Tk() aplikace = Aplikace(root) root.mainloop()
V kóde vytvárame atribút db
, do ktorého v konstruktoru
uložíme novú inštanciu našej databázy. Do aplikácie pridávame tiež
nové tlačidlo a nastavujeme automaticky veľkosť formulára metódou
pack()
. Metódu tlacitkoUlozitClicked()
sme
zaregistrovali, aby sa zavolala po kliknutí na tlačidlo.
Zvyšok kódu mimo triedu Aplikace
sa stará o vytvorenie okna
po spustení programu. Tkinter je prípadne detailne vysvetlený v článku Úvod
do tkinteru v Pythone.
V jeho Click Handler (naša metóda tlacitkoUlozitClicked()
)
pridáme do databázy 2 používateľa. Bude to teraz pre vyskúšanie, neskôr
bude aplikácia vyzerať lepšie. Ďalej celú databázu uložíme do
súboru.
def tlacitkoUlozitClicked(self): self.db.pridejUzivatele("Pavel Slavík", 22, datetime.datetime(2000, 3, 21)) self.db.pridejUzivatele("Jan Novák", 31, datetime.datetime(2012, 10, 30)) self.db.uloz()
Aplikáciu spustíme. Potom otvoríme (napr. V notepad) súbor
uzivatele.csv
, ktorý sa v jej zložke vytvoril, a vidíme, že má
nasledujúci obsah:
Pavel Slavík;22;21.3.2000 Jan Novák;31;30.10.2012
Všetko teda funguje, ako má Načítanie užívateľov a dokončenie aplikácie si necháme na budúci lekciu, Riešené úlohy k 1.-5. lekciu práca so súbormi v Pythone .
V nasledujúcom cvičení, Riešené úlohy k 1.-5. lekciu práca so súbormi v Pythone, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 268x (1.26 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python