JSON: zapisywanie danych strukturalnych

Witaj z powrotem.
W poprzedniej lekcji nauczyłeś się modułów i importów.
Twoje programy nauczyły się dzielić kod na wiele plików.
Pisałeś projekty takie jak:
main.py
tasks.py
safe_input.py
Bardzo dobrze.
Twój kod jest teraz bardziej uporządkowany.
Mniej gigantycznego pliku.
Mniej lasagne z kodu.
Mniej “gdzie ja włożyłem tę funkcję?”
Świetny postęp.
Ale teraz mamy kolejny problem.
W poprzednich lekcjach zapisywaliśmy dane w zwykłych plikach tekstowych.
Na przykład:
Anna,anna@example.com,123456
Marco,marco@example.com,987654
To działa.
Ale nie jest idealne.
Co jeśli dane staną się bardziej złożone?
Co jeśli jeden kontakt ma więcej pól?
Co jeśli chcesz zapisać listę słowników?
Co jeśli użytkownik wpisze przecinek w imieniu?
Chaos.
Pliki tekstowe są użyteczne.
Ale do danych strukturalnych JSON jest lepszy.
JSON pozwala zapisywać dane takie jak:
contact = {
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
do pliku.
A potem załadować je później z powrotem.
To bardzo ważne.
JSON jest używany wszędzie.
API.
Aplikacje webowe.
Pliki konfiguracyjne.
Bazy danych.
Komunikacja między frontendem i backendem.
Małe skrypty, które przypadkiem stają się prawdziwym software.
Bardzo użyteczne.
Bardzo praktyczne.
Bardzo przyjazne dla Pythona.
Czego się nauczysz
W tej lekcji nauczysz się:
- czym jest JSON;
- dlaczego JSON jest użyteczny;
- jak wygląda JSON;
- dlaczego JSON jest podobny do słowników i list Pythona;
- jak importować moduł
json; - jak zapisywać dane przez
json.dump(); - jak ładować dane przez
json.load(); - jak zapisać słownik;
- jak zapisać listę słowników;
- jak ładnie formatować JSON przez
indent; - jak obsługiwać brakujące pliki JSON;
- jak zbudować książkę kontaktów używając JSON;
- typowych błędów początkujących z JSON.
Pod koniec tej lekcji twoje programy będą potrafiły poprawnie zapisywać dane strukturalne.
Nie tylko proste linie.
Prawdziwe dane.
Listy.
Słowniki.
Informacje zagnieżdżone.
Bardzo potężne.
Bardzo użyteczne.
Bardzo “teraz to zaczyna wyglądać jak prawdziwa aplikacja”.
Czym jest JSON?
JSON oznacza:
JavaScript Object Notation
Nie panikuj.
Mimo że w nazwie jest JavaScript, JSON jest używany przez wiele języków.
Python używa JSON.
JavaScript używa JSON.
Java używa JSON.
API używają JSON.
Aplikacje webowe używają JSON.
Wszyscy używają JSON.
JSON to format tekstowy do przechowywania i wymiany danych.
Wygląda tak:
{
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
Wygląda znajomo?
Jest bardzo podobny do słownika Pythona.
Słownik Python:
contact = {
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
JSON:
{
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
Bardzo podobne.
Nie dokładnie to samo.
Ale wystarczająco podobne, żeby wyglądało przyjaźnie.
Jak kuzyni.
Jeden mówi Pythonem.
Drugi mówi webem.
Dlaczego JSON jest użyteczny
JSON jest użyteczny, bo potrafi przechowywać dane strukturalne.
Na przykład jeden kontakt:
{
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
Lista kontaktów:
[
{
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
},
{
"name": "Marco",
"email": "marco@example.com",
"phone": "987654"
}
]
To jest dużo lepsze niż zwykły tekst:
Anna,anna@example.com,123456
Marco,marco@example.com,987654
Dlaczego?
Bo JSON zachowuje strukturę.
Wie, że każdy kontakt ma:
name
email
phone
Może przechowywać listy.
Może przechowywać słowniki.
Może przechowywać dane zagnieżdżone.
Zwykły tekst jest jak zapisanie wszystkiego na serwetce.
JSON jest jak mały uporządkowany formularz.
Nadal tekst.
Ale ze strukturą.
Bardzo ładnie.
Importowanie modułu json
Python ma wbudowany moduł do JSON.
Nazywa się:
json
Żeby go użyć, zaimportuj go:
import json
Nie musisz nic instalować.
Python już go zawiera.
Bardzo wygodnie.
Bardzo cywilizowanie.
Bardzo “w końcu coś działa bez instalowania siedemnastu paczek”.
Podstawowa idea:
import json
Potem możesz używać:
json.dump()
json.load()
Te dwie funkcje są bardzo ważne.
dump zapisuje dane do pliku.
load ładuje dane z pliku.
Proste.
Prawie zbyt proste.
Nie martw się.
Później i tak zrobi się trochę zamieszania.
Tak działa programowanie.
Zapisywanie słownika do JSON
Utwórz plik:
save_contact.py
Napisz:
import json
contact = {
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
with open("contact.json", "w") as file:
json.dump(contact, file)
Uruchom:
python save_contact.py
albo:
python3 save_contact.py
Python utworzy plik:
contact.json
W środku możesz zobaczyć:
{"name": "Anna", "email": "anna@example.com", "phone": "123456"}
To jest poprawny JSON.
Niezbyt piękny.
Ale poprawny.
Ta linia zapisuje słownik:
json.dump(contact, file)
Ważne:
json.dump(data, file)
oznacza:
Zapisz te dane Pythona do tego pliku jako JSON.
Bardzo użyteczne.
Bardzo czyste.
Bardzo strukturalne.
Ładny JSON z indent
Poprzedni JSON działa, ale jest cały w jednej linii.
Możemy zrobić go ładniejszym.
Użyj indent=4.
Przykład:
import json
contact = {
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
with open("contact.json", "w") as file:
json.dump(contact, file, indent=4)
Teraz contact.json wygląda tak:
{
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
Dużo lepiej.
Dużo łatwiej czytać.
Dużo mniej “spaghetti JSON”.
Używaj indent=4, kiedy chcesz JSON czytelny dla ludzi.
Komputerom to obojętne.
Ludziom nie.
A niestety jesteś człowiekiem.
Przez większość dni.
Ładowanie słownika z JSON
Teraz odczytajmy plik JSON z powrotem.
Utwórz plik:
load_contact.py
Napisz:
import json
with open("contact.json", "r") as file:
contact = json.load(file)
print(contact)
print(contact["name"])
print(contact["email"])
print(contact["phone"])
Output:
{'name': 'Anna', 'email': 'anna@example.com', 'phone': '123456'}
Anna
anna@example.com
123456
Ta linia ładuje JSON z pliku:
contact = json.load(file)
Po załadowaniu contact znowu jest słownikiem Pythona.
To jest magia.
Nie fałszywa magia.
Użyteczna magia.
Workflow:
Słownik Python
zapis jako JSON
ładowanie z JSON
znowu słownik Python
Bardzo ważne.
Bardzo praktyczne.
Bardzo real-world.
json.dump() vs json.load()
Te dwie nazwy są ważne.
json.dump(data, file)
zapisuje dane do pliku.
json.load(file)
ładuje dane z pliku.
Pamiętaj:
dump = zapisz
load = odczytaj
Przykład:
json.dump(contact, file)
oznacza:
Zapisz contact do pliku.
Przykład:
contact = json.load(file)
oznacza:
Odczytaj JSON z pliku i zamień go na dane Pythona.
Ta para jest używana ciągle.
Jeśli zapamiętasz tylko jedną rzecz z tej lekcji, zapamiętaj:
json.dump() zapisuje.
json.load() ładuje.
To serce obsługi plików JSON.
Małe serce.
Bardzo użyteczne serce.
Zapisywanie listy do JSON
JSON może zapisywać też listy.
Utwórz:
save_tasks_json.py
Napisz:
import json
tasks = [
"Buy milk",
"Study Python",
"Drink coffee"
]
with open("tasks.json", "w") as file:
json.dump(tasks, file, indent=4)
Plik tasks.json będzie zawierał:
[
"Buy milk",
"Study Python",
"Drink coffee"
]
To jest tablica JSON.
W Pythonie nazywamy to listą.
W JSON nazywa się to array.
Ta sama idea.
Inne słownictwo.
Programowanie kocha dawać tej samej rzeczy różne nazwy.
Trzyma nas to w pokorze.
I lekko denerwuje.
Ładowanie listy z JSON
Utwórz:
load_tasks_json.py
Napisz:
import json
with open("tasks.json", "r") as file:
tasks = json.load(file)
for task in tasks:
print(f"- {task}")
Output:
- Buy milk
- Study Python
- Drink coffee
Tablica JSON stała się listą Pythona.
Bardzo użyteczne.
To jest lepsze niż ręczne czytanie linii.
Przy zwykłym tekście robiliśmy:
for line in file:
tasks.append(line.strip())
Z JSON Python może automatycznie załadować całą strukturę:
tasks = json.load(file)
Czyściej.
Mocniej.
Mniej ręcznej chirurgii na stringach.
Świetnie.
Zapisywanie listy słowników
Tutaj JSON robi się naprawdę użyteczny.
Utwórz:
save_contacts_json.py
Napisz:
import json
contacts = [
{
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
},
{
"name": "Marco",
"email": "marco@example.com",
"phone": "987654"
}
]
with open("contacts.json", "w") as file:
json.dump(contacts, file, indent=4)
Plik contacts.json będzie zawierał:
[
{
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
},
{
"name": "Marco",
"email": "marco@example.com",
"phone": "987654"
}
]
To jest dużo lepsze niż:
Anna,anna@example.com,123456
Marco,marco@example.com,987654
Bo struktura jest jasna.
Każdy kontakt jest obiektem.
Każdy obiekt ma klucze.
Lista zawiera kontakty.
Pięknie.
Uporządkowanie.
Jak szafka na dokumenty.
Tylko mniej zakurzona.
Ładowanie listy słowników
Utwórz:
load_contacts_json.py
Napisz:
import json
with open("contacts.json", "r") as file:
contacts = json.load(file)
for contact in contacts:
print("-----")
print(f"Name: {contact['name']}")
print(f"Email: {contact['email']}")
print(f"Phone: {contact['phone']}")
Output:
-----
Name: Anna
Email: anna@example.com
Phone: 123456
-----
Name: Marco
Email: marco@example.com
Phone: 987654
Teraz możesz zapisywać i ładować strukturalne dane kontaktów.
To jest realne.
Ten pattern pojawia się wszędzie.
Lista słowników to jedna z najczęstszych struktur danych dla początkujących.
JSON zapisuje ją pięknie.
Python ładuje ją łatwo.
Bardzo dobrze.
Bardzo praktycznie.
Bardzo backend-friendly.
Typy Python i JSON
Dane Pythona stają się danymi JSON.
Podstawowa konwersja:
Python dict -> JSON object
Python list -> JSON array
Python string -> JSON string
Python int/float -> JSON number
Python True -> JSON true
Python False -> JSON false
Python None -> JSON null
Przykład Python:
data = {
"name": "Anna",
"age": 25,
"active": True,
"skills": ["Python", "HTML", "CSS"],
"address": None
}
JSON:
{
"name": "Anna",
"age": 25,
"active": true,
"skills": [
"Python",
"HTML",
"CSS"
],
"address": null
}
Zauważ:
True staje się true
False staje się false
None staje się null
Małe różnice.
Ważne różnice.
JSON nie jest dokładnie Pythonem.
Po prostu wygląda jak Python po herbacie z JavaScriptem.
Ważne zasady JSON
JSON ma zasady.
Bardzo surowe zasady.
Stringi muszą używać podwójnych cudzysłowów:
"name"
Nie pojedynczych:
'name'
Poprawny JSON:
{
"name": "Anna"
}
Niepoprawny JSON:
{
'name': 'Anna'
}
JSON nie pozwala też na przecinki na końcu.
Poprawnie:
{
"name": "Anna",
"age": 25
}
Źle:
{
"name": "Anna",
"age": 25,
}
Słowniki Pythona pozwalają na więcej elastyczności.
JSON jest bardziej surowy.
Bardzo surowy.
Jak nauczyciel z linijką.
Ale dla danych.
Obsługa brakujących plików JSON
Jeśli spróbujesz załadować plik JSON, który nie istnieje, Python da:
FileNotFoundError
Przykład:
import json
with open("missing.json", "r") as file:
data = json.load(file)
Bezpieczniejsza wersja:
import json
try:
with open("contacts.json", "r") as file:
contacts = json.load(file)
except FileNotFoundError:
contacts = []
print(contacts)
Jeśli plik istnieje, kontakty zostaną załadowane.
Jeśli nie istnieje, contacts stanie się pustą listą.
To jest użyteczne przy pierwszym uruchomieniu.
Nowy program.
Jeszcze brak danych.
Brak katastrofy.
Tylko pusta lista czekająca na życie.
Bardzo poetycko.
Jak na plik.
Zapisywanie po zmianach
Podczas pracy z JSON normalny pattern to:
załaduj dane
zmień dane
zapisz dane
Przykład:
import json
try:
with open("contacts.json", "r") as file:
contacts = json.load(file)
except FileNotFoundError:
contacts = []
new_contact = {
"name": "Sofia",
"email": "sofia@example.com",
"phone": "555000"
}
contacts.append(new_contact)
with open("contacts.json", "w") as file:
json.dump(contacts, file, indent=4)
To robi:
Ładuje kontakty.
Jeśli pliku nie ma, startuje z pustą listą.
Dodaje nowy kontakt.
Zapisuje zaktualizowaną listę.
Ten pattern jest ekstremalnie ważny.
Będziesz go używać wiele razy.
Załaduj.
Zmień.
Zapisz.
Święty trójkąt małych programów z danymi.
Bardzo użyteczne.
Bardzo praktyczne.
Bardzo łatwo zapomnieć jeden bok i zastanawiać się, czemu nic się nie zapisało.
Mini program: zapis profilu jako JSON
Utwórz:
profile_json.py
Napisz:
import json
profile = {
"name": input("Name: "),
"city": input("City: "),
"job": input("Job: ")
}
with open("profile.json", "w") as file:
json.dump(profile, file, indent=4)
print("Profile saved.")
Przykładowy input:
Name: Anna
City: Rome
Job: Developer
Plik profile.json:
{
"name": "Anna",
"city": "Rome",
"job": "Developer"
}
To proste.
Ale mocne.
Zapisałeś słownik jako dane strukturalne.
Możesz odczytać go później.
Możesz go edytować.
Możesz użyć go w innym programie.
Mały projekt.
Realna idea.
Mini program: ładowanie profilu z JSON
Utwórz:
show_profile_json.py
Napisz:
import json
try:
with open("profile.json", "r") as file:
profile = json.load(file)
print("----- Profile -----")
print(f"Name: {profile['name']}")
print(f"City: {profile['city']}")
print(f"Job: {profile['job']}")
except FileNotFoundError:
print("No profile found.")
Output:
----- Profile -----
Name: Anna
City: Rome
Job: Developer
Teraz twój program może ładować dane strukturalne.
To duży krok.
Profil w zwykłym tekście wymagałby ręcznego parsowania.
JSON robi to bezpośrednio.
Bez split.
Bez przecinków.
Bez chirurgii na stringach.
Po prostu załaduj i użyj.
Pięknie.
Mini program: task manager JSON
Utwórz:
json_task_manager.py
Napisz:
import json
FILE_NAME = "tasks.json"
def load_tasks():
try:
with open(FILE_NAME, "r") as file:
return json.load(file)
except FileNotFoundError:
return []
def save_tasks(tasks):
with open(FILE_NAME, "w") as file:
json.dump(tasks, file, indent=4)
def show_menu():
print("----- JSON Task Manager -----")
print("1. Add task")
print("2. Show tasks")
print("3. Remove task")
print("q. Quit")
def add_task(tasks):
task = {
"title": input("Task title: "),
"done": False
}
tasks.append(task)
save_tasks(tasks)
print("Task saved.")
def show_tasks(tasks):
if len(tasks) == 0:
print("No tasks yet.")
else:
print("Tasks:")
for index, task in enumerate(tasks, start=1):
status = "done" if task["done"] else "not done"
print(f"{index}. {task['title']} - {status}")
def remove_task(tasks):
if len(tasks) == 0:
print("No tasks to remove.")
return
show_tasks(tasks)
try:
task_number = int(input("Task number to remove: "))
index = task_number - 1
if index < 0 or index >= len(tasks):
print("Invalid task number.")
return
removed_task = tasks.pop(index)
save_tasks(tasks)
print(f"Removed: {removed_task['title']}")
except ValueError:
print("Please enter a valid number.")
tasks = load_tasks()
while True:
show_menu()
choice = input("Choose an option: ").lower()
if choice == "1":
add_task(tasks)
elif choice == "2":
show_tasks(tasks)
elif choice == "3":
remove_task(tasks)
elif choice == "q":
print("Goodbye.")
break
else:
print("Unknown option.")
Ten task manager zapisuje zadania jako słowniki.
Każde zadanie ma:
title
done
Przykład JSON:
[
{
"title": "Study Python",
"done": false
},
{
"title": "Drink coffee",
"done": false
}
]
To lepsze niż zwykła lista nazw zadań.
Bo teraz każde zadanie może mieć więcej informacji.
Później możesz dodać:
priority
deadline
category
created_at
JSON rośnie lepiej niż zwykły tekst.
Zwykły tekst jest dobry do prostych danych.
JSON jest lepszy do danych strukturalnych.
Mini program: książka kontaktów JSON
Utwórz:
json_contact_book.py
Napisz:
import json
FILE_NAME = "contacts.json"
def load_contacts():
try:
with open(FILE_NAME, "r") as file:
return json.load(file)
except FileNotFoundError:
return []
def save_contacts(contacts):
with open(FILE_NAME, "w") as file:
json.dump(contacts, file, indent=4)
def show_menu():
print("----- JSON Contact Book -----")
print("1. Add contact")
print("2. Show contacts")
print("q. Quit")
def add_contact(contacts):
contact = {
"name": input("Name: "),
"email": input("Email: "),
"phone": input("Phone: ")
}
contacts.append(contact)
save_contacts(contacts)
print("Contact saved.")
def show_contacts(contacts):
if len(contacts) == 0:
print("No contacts yet.")
else:
print("Contacts:")
for contact in contacts:
print("-----")
print(f"Name: {contact['name']}")
print(f"Email: {contact['email']}")
print(f"Phone: {contact['phone']}")
contacts = load_contacts()
while True:
show_menu()
choice = input("Choose an option: ").lower()
if choice == "1":
add_contact(contacts)
elif choice == "2":
show_contacts(contacts)
elif choice == "q":
print("Goodbye.")
break
else:
print("Unknown option.")
To prawdziwa aplikacja dla początkujących.
Używa:
- słowników;
- list;
- plików;
- JSON;
- funkcji;
- pętli;
- warunków;
- obsługi błędów.
Bardzo mocne.
Bardzo użyteczne.
Bardzo realne.
Twoje dane kontaktów są teraz strukturalne i poprawnie zapisane.
To dużo lepsze niż tekst rozdzielony przecinkami.
Bo jeśli później dodasz:
address
birthday
notes
company
JSON poradzi sobie ładnie.
Zwykły tekst zaczyna się pocić.
Typowy błąd: zapomnienie import json
Źle:
with open("data.json", "w") as file:
json.dump(data, file)
Jeśli nie napisałeś:
import json
Python da:
NameError
Poprawnie:
import json
with open("data.json", "w") as file:
json.dump(data, file)
Zawsze importuj moduł przed użyciem.
Python jest potężny.
Ale nie zgaduje automatycznie twoich importów.
Nie czyta w myślach.
Na szczęście.
Typowy błąd: używanie dump i load odwrotnie
Źle:
data = json.dump(file)
Źle:
json.load(data, file)
Poprawnie:
json.dump(data, file)
Poprawnie:
data = json.load(file)
Pamiętaj:
dump bierze dane i plik
load bierze plik i zwraca dane
Mała sztuczka pamięciowa:
dump data into a file
load data from a file
Jeśli to wydaje się mylące, to normalne.
Nazwy są krótkie.
Zamieszanie jest długie.
Praktyka pomaga.
Typowy błąd: próba zapisania nieobsługiwanych danych
JSON może zapisywać popularne typy:
dict
list
str
int
float
bool
None
Ale nie wszystko.
Na przykład to może się nie udać:
data = {
"numbers": {1, 2, 3}
}
Dlaczego?
Bo {1, 2, 3} to set.
JSON nie obsługuje bezpośrednio pythonowych setów.
Jeśli musisz zapisać set, zamień go na listę:
data = {
"numbers": list({1, 2, 3})
}
Dla początkujących używaj:
słowników
list
stringów
liczb
booleanów
None
Te typy dobrze działają z JSON.
Trzymaj prosto.
Proste przeżywa.
Skomplikowane prosi o kawę.
Typowy błąd: niepoprawny plik JSON
Jeśli plik JSON jest zepsuty, json.load() może się nie udać.
Przykład niepoprawnego JSON:
{
"name": "Anna",
}
Przecinek na końcu sprawia, że JSON jest niepoprawny.
Python może zgłosić:
json.JSONDecodeError
Bezpieczniejsze ładowanie:
import json
try:
with open("data.json", "r") as file:
data = json.load(file)
except FileNotFoundError:
data = []
except json.JSONDecodeError:
print("JSON file is broken.")
data = []
To obsługuje:
brakujący plik
zepsuty plik JSON
Bardzo użyteczne.
Szczególnie kiedy ludzie ręcznie edytują JSON.
Ludzie i przecinki to niebezpieczna kombinacja.
Bardzo niebezpieczna.
Typowy błąd: zapomnienie zapisu po append
Źle:
contacts = load_contacts()
contact = {
"name": "Anna",
"email": "anna@example.com",
"phone": "123456"
}
contacts.append(contact)
print("Contact added.")
To dodaje kontakt tylko w pamięci.
Ale nie zapisuje go do pliku.
Kiedy program się kończy, nowy kontakt znika.
Poprawnie:
contacts.append(contact)
save_contacts(contacts)
Pamiętaj pattern:
load
modify
save
Jeśli zmieniasz dane, ale ich nie zapisujesz, plik się nie zmienia.
Python nie zapisze tego emocjonalnie.
Musisz mu powiedzieć.
Jasno.
Kodом.
Typowy błąd: otwieranie JSON w trybie append
To zwykle jest złe:
with open("contacts.json", "a") as file:
json.dump(contact, file)
Dopisywanie obiektów JSON bezpośrednio może stworzyć niepoprawny JSON.
Przykład zepsutego pliku:
{"name": "Anna"}{"name": "Marco"}
To nie jest poprawna lista JSON.
Dla plików JSON zwykle rób tak:
załaduj istniejącą listę
dodaj element do listy
zapisz całą listę ponownie
Przykład:
contacts = load_contacts()
contacts.append(new_contact)
save_contacts(contacts)
To utrzymuje plik JSON poprawnym.
Tryb append jest użyteczny dla zwykłych logów tekstowych.
Dla danych strukturalnych JSON uważaj.
Bardzo uważaj.
JSON lubi strukturę.
Nie losowe obiekty przyklejone do siebie.
Praktyka
Utwórz:
practice_json.py
Napisz program, który:
- pyta użytkownika o tytuł książki;
- pyta użytkownika o autora;
- pyta użytkownika o rok;
- zapisuje książkę jako JSON w
book.json; - ładuje książkę z powrotem;
- ładnie ją wypisuje.
Przykładowe rozwiązanie:
import json
book = {
"title": input("Title: "),
"author": input("Author: "),
"year": input("Year: ")
}
with open("book.json", "w") as file:
json.dump(book, file, indent=4)
with open("book.json", "r") as file:
loaded_book = json.load(file)
print("----- Book -----")
print(f"Title: {loaded_book['title']}")
print(f"Author: {loaded_book['author']}")
print(f"Year: {loaded_book['year']}")
Ta praktyka uczy:
- tworzenia słownika;
- zapisywania słownika jako JSON;
- ładowania JSON;
- używania załadowanego słownika.
Prosto.
Użytecznie.
Bardzo strukturalnie.
Bardzo dobrze.
Mini wyzwanie
Utwórz:
library_json.py
Zbuduj mały program biblioteczny, który:
- zapisuje książki do
books.json; - ładuje książki przy starcie;
- pozwala użytkownikowi dodać książkę;
- pozwala użytkownikowi pokazać wszystkie książki;
- każda książka ma title, author i year;
- bezpiecznie obsługuje brakujący plik.
Przykładowa struktura:
import json
FILE_NAME = "books.json"
def load_books():
try:
with open(FILE_NAME, "r") as file:
return json.load(file)
except FileNotFoundError:
return []
def save_books(books):
with open(FILE_NAME, "w") as file:
json.dump(books, file, indent=4)
def add_book(books):
book = {
"title": input("Title: "),
"author": input("Author: "),
"year": input("Year: ")
}
books.append(book)
save_books(books)
print("Book saved.")
def show_books(books):
if len(books) == 0:
print("No books yet.")
else:
print("Books:")
for book in books:
print("-----")
print(f"Title: {book['title']}")
print(f"Author: {book['author']}")
print(f"Year: {book['year']}")
def show_menu():
print("----- Library -----")
print("1. Add book")
print("2. Show books")
print("q. Quit")
books = load_books()
while True:
show_menu()
choice = input("Choose an option: ").lower()
if choice == "1":
add_book(books)
elif choice == "2":
show_books(books)
elif choice == "q":
print("Goodbye.")
break
else:
print("Unknown option.")
To prawdziwa mała aplikacja.
Używa JSON do przechowywania listy słowników.
To bardzo ważny pattern.
Bardzo użyteczny dla przyszłych projektów.
Możesz dostosować tę strukturę do:
contacts
tasks
products
students
courses
expenses
workouts
Idea jest taka sama.
Załaduj dane.
Zmień dane.
Zapisz dane.
Gratulacje.
Budujesz wielokrotnego użytku patterny.
Tak rosną developerzy.
Powoli.
Boleśnie.
Ze snackami.
Extra challenge: ulepsz task manager
Weź JSON task manager i dodaj nową opcję:
4. Mark task as done
Każde zadanie już ma:
"done": False
Twoje zadanie:
- pokaż zadania z numerami;
- zapytaj, które zadanie oznaczyć jako wykonane;
- zmień
"done"naTrue; - zapisz zadania ponownie.
Podpowiedź:
tasks[index]["done"] = True
save_tasks(tasks)
To bardzo dobre wyzwanie.
Uczy aktualizowania danych strukturalnych.
Nie tylko dodawania.
Nie tylko usuwania.
Aktualizowania.
To robią prawdziwe aplikacje cały czas.
Create.
Read.
Update.
Delete.
Później usłyszysz, że to nazywa się CRUD.
Bardzo poważne słowo.
Bardzo prosta idea.
Bardzo użyteczna.
Checklist dla początkujących
Kiedy kod JSON nie działa, sprawdź:
Czy zaimportowałem json?
Czy używam json.dump(data, file)?
Czy używam data = json.load(file)?
Czy otworzyłem plik w poprawnym trybie?
Czy użyłem indent=4 dla czytelnego JSON?
Czy plik istnieje przed czytaniem?
Czy powinienem obsłużyć FileNotFoundError?
Czy plik JSON jest poprawny?
Czy przypadkiem zostawiłem przecinek na końcu?
Czy próbuję zapisać nieobsługiwany typ Pythona?
Czy zapisałem po zmianie danych?
Czy źle dopisuję do JSON?
Błędy JSON zwykle dotyczą:
brakującego pliku
niepoprawnego JSON
złego użycia dump/load
zapomnianego save
złej struktury danych
Napraw spokojnie.
Przeczytaj komunikat błędu.
Sprawdź plik.
Sprawdź dane.
Wypij kawę, jeśli trzeba.
Ale nie rzucaj laptopem.
Laptop jest niewinny.
Zwykle.
Podsumowanie
Dzisiaj nauczyłeś się:
- JSON to popularny format danych strukturalnych;
- JSON wygląda podobnie do słowników i list Pythona;
- Python używa wbudowanego modułu
json; json.dump()zapisuje dane Pythona do pliku JSON;json.load()ładuje dane JSON z pliku;indent=4sprawia, że JSON jest czytelny;- słowniki można zapisywać jako obiekty JSON;
- listy można zapisywać jako tablice JSON;
- listy słowników są bardzo użyteczne z JSON;
True,FalseiNonestają siętrue,falseinull;- JSON wymaga podwójnych cudzysłowów;
- JSON nie pozwala na przecinki na końcu;
- brakujące pliki JSON można obsłużyć przez
FileNotFoundError; - zepsuty JSON może zgłosić
json.JSONDecodeError; - powszechny pattern to załaduj, zmień, zapisz;
- JSON jest lepszy niż zwykły tekst dla danych strukturalnych.
To duży krok.
Twoje programy mogą teraz zapisywać prawdziwe dane strukturalne.
Nie tylko linie tekstu.
Mogą zapisywać kontakty.
Zadania.
Książki.
Profile.
Produkty.
Wszystko, co mieści się w słownikach i listach.
To taki typ struktury danych, którego używa się w prawdziwych aplikacjach.
Małe programy dla początkujących stają się teraz poważne.
Nadal małe.
Ale poważne.
Jak malutki inżynier z clipboardem.
Następna lekcja
W następnej lekcji nauczymy się virtual environments i instalowania paczek.
Do tej pory używaliśmy tylko wbudowanych narzędzi Pythona.
Ale prawdziwe projekty Python często używają zewnętrznych paczek.
Nauczysz się tworzyć virtual environment:
python -m venv .venv
Aktywować go.
Instalować paczki przez pip.
I utrzymywać zależności projektu w porządku.
To bardzo ważne przed budowaniem większych projektów.
Bo instalowanie paczek globalnie to sposób, w jaki zaczyna się chaos.
A chaosu mamy już wystarczająco.
Bardzo Python.
Bardzo real-world.
Bardzo konieczne.