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 z minula bola jednoduchá a skôr učebnicová. Urobme si teraz skutočnú 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ázu 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 použí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ď nezasvätený 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 použí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 napíšme
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 konštruktorom.
V konštruktore si uložíme cestu k databázovému súboru:
def __init__(self, soubor): self.soubor = soubor
To bolo veľmi jednoduché a aj na ďalšej 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 na vyhľadávanie len niektorých
užívateľov. Užívateľa navrá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štanciou file handlera získanou funkciou
open()
. Vnútri proiterujeme náš zoznam používateľov a pre
každého použí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 (oddeľovači) 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ácie pred uložením do súboru naformátujeme na "deň.mesiac.rok".
Aplikácia
Naša aplikácia bude formulárová pomocou knižnice tkinter
.
Pokiaľ 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úcu 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 konštruktore
uložíme novú inštanciu našej databázy. Do aplikácie pridávame aj 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 triedy 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 handleri (naša metóda tlacitkoUlozitClicked()
)
pridáme do databázy 2 užívateľov. Bude to teraz na 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 NotePade) súbor
uzivatele.csv
, ktorý sa v jej priečinku 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á:)
V ďalšej lekcii, Uloženie objektov do CSV v Pythone časť 2 , načítame do aplikácie používateľa.
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é 285x (1.26 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python