4. diel - Uloženie objektov do CSV v Pythone
V predchádzajúcej 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 použí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ť.
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 User. U
použí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 User(): def __init__(self, name, age, registered): self.name = name self.age = age self.registered = registered def __str__(self): return self.name
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 používateľa budú oddelené bodkočiarkami. Používateľ John Smith, ktorý má 22 rokov a zaregistroval sa 21.3.2000 by vyzeral takto:
John Smith;22;03/21/2000
Na prvý pohľad vidíme, že je súbor relatívne jednoducho čitateľný,
aj keď niekto nezainteresovaný sa môže len domnievať, čo je číslo
22 a na čo sa viaže daný dátum.
V súbore môže byť samozrejme viac používateľov, teda viac riadkov.
Triedu použí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
používateľov, tvorenú zoznamom. Pridávanie použí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 Database a napíšme
jej kostru:
class Database(): users = [] def __init__(self, file): pass def addUser(self, name, age, registered): pass def returnAll(self): pass def save(self): pass def load(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, file): self.file = file
To bolo veľmi jednoduché a aj pri ďalšej metóde nie je čo vymýšľať:
def addUser(self, name, age, registered):
u = User(name, age, registered)
self.users.append(u)
Metóda returnAll() nám vráti všetkých používateľov.
Podobne môžeme v budúcnosti urobiť metódy na vyhľadávanie len niektorých
používateľov:
def returnAll(self): return self.users
Uloženie používateľov do CSV
Teraz sa konečne dostávame k práci s CSV súborom. Začneme blokom
with a inštanciou file handlerom získanou funkciou
open(). Vnútri preiterujeme náš zoznam používateľov a pre
každého používateľa vytvoríme zoznam reťazcov z jeho vlastností.
Nestringové vlastnosti musíme na string explicitne previesť. Hodnoty 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 save(self): with open(self.file, "w", encoding="utf-8") as f: for u in self.users: values = [u.name, str(u.age), u.registered.strftime("%m/%d/%Y")] line = ";".join(values) f.write(line + "\n")
Všimnite si, že dátum registrácie pred uložením do súboru naformátujeme na "mesiac/deň/rok".
Aplikácia
Naša aplikácia bude formulárová pomocou knižnice tkinter.
Ak preferujete PyQt,
bude pre vás vďaka jej jednoduchosti bezproblémové ju upraviť aj pre túto
knižnicu.
Do main.py si vložme poslednú triedu, reprezentujúcu okno
aplikácie:
class Application(tkinter.Frame): def __init__(self, master): super().__init__(master=master) self.master = master self.pack() self.db = Database("users.csv") self.master.title("Lesson4") self.buttonSave = tkinter.Button(self.master, text="Save", width=40, command=self.buttonSaveClicked) self.buttonSave.pack(fill=tkinter.X) def buttonSaveClicked(self): pass root = tkinter.Tk() application = Application(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 buttonSaveClicked() sme
zaregistrovali, aby sa zavolala po kliknutí na tlačidlo.
Zvyšok kódu mimo triedy Application sa stará o vytvorenie
okna po spustení programu. Tkinter je detailne vysvetlený v článku Úvod
do tkinteru v Pythone.

V jeho Click handleri (naša metóda buttonSaveClicked())
pridáme do databázy 2 používateľov. Teraz bude na vyskúšanie, neskôr
bude aplikácia vyzerať lepšie. Ďalej celú databázu uložíme do
súboru.
def buttonSaveClicked(self): self.db.addUser("John Smith", 22, datetime.datetime(2000, 3, 21)) self.db.addUser("James Brown", 31, datetime.datetime(2012, 10, 30)) self.db.save()
Aplikáciu spustíme. Potom otvoríme (napr. v NotePade) súbor
users.csv, ktorý sa v jej priečinku vytvoril, a vidíme, že má
nasledujúci obsah:
John Smith;22;3/21/2000 James Brown;31;10/30/2012
Všetko teda funguje tak, ako má 
V nasledujúcej 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é 33x (2 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python
