Ачааллж байна...
Бид одоо хоёр хүчирхэг хэрэгсэлтэй болсон, гэхдээ тэдгээр нь хоорондоо ярьдаггүй.
Бүлэг 6-д бид JSON-ыг сурсан: json.dump() ба json.load() -ээр өгөгдлийг файлд хадгалж, буцааж унших. Гэвч тэр үед бидний өгөгдөл нь dictionary байсан.
Бүлэг 9-д бид dataclass-ыг сурсан: цэвэрхэн, type hint-тэй, editor нь бүрэн тусалдаг. Гэвч тэр нь зөвхөн САНАХ ОЙД амьдарч байна — программ хаагдахад алга болно.
Одоо тэдгээрийг холбох цаг болжээ.
Гэвч эхлээд асуудлыг харъя:
python
import json
from dataclasses import dataclass
@dataclass
class Zarlaga:
ner: str
dun: int
angilal: str
z = Zarlaga("Ном", 15000, "боловсрол")
print(json.dumps(z))Traceback (most recent call last):
File "main.py", line 13, in <module>
print(json.dumps(z))
TypeError: Object of type Zarlaga is not JSON serializableTypeError: Object of type Zarlaga is not JSON serializable гэдэг нь "Zarlaga төрлийн объектыг JSON болгож хөрвүүлэх боломжгүй" гэсэн үг.
Бүлэг 6.2-оос танил алдаа! Тэнд бид set-ийг JSON-д хадгалж чадаагүй, яг ижил мессежтэй.
Учир нь: JSON-д class гэж байхгүй. Бүлэг 6.1-ээс санаж байгаа байх — JSON-д зөвхөн зургаан төрөл байдаг: string, number, true/false, null, array, object. Class нь тэдний нэг ч биш.
Тэгэхээр асуудал тодорхой: Python-ы объект ↔ JSON хооронд ГҮҮР хэрэгтэй.
Бүлэг 6.1-ийн "нийтлэг хэл" зүйрлэлийг санаж байна уу? Тэнд JSON нь программуудын хоорондох англи хэл байсан.
Одоо танд шинэ асуудал байна: та монголоор бичсэн, гэхдээ өөрийн гэсэн тусгай нэр томьёо ашигласан баримт бичигтэй. Тэр баримтыг гадаад руу илгээх гэж байна.
Орчуулагч түүнийг англи руу орчуулж чадна — гэхдээ таны тусгай нэр томьёог ойлгохгүй. Тэр "Zarlaga" гэсэн үгийг харахад юу гэж орчуулахаа мэдэхгүй.
Шийдэл: та түүнд ЗААЖ ӨГӨХ. "Zarlaga гэдэг нь гурван хэсэгтэй: нэр, дүн, ангилал. Тэднийг ингэж бич."
Тэгээд буцаж ирэхэд эсрэг ажил хийнэ: "энэ гурван хэсгээс Zarlaga -г буцааж угса."
Тэр хоёр ажлыг программын ертөнцөд:
Serialize (савлах) — объект → dictionary → JSON
Deserialize (задлах) — JSON → dictionary → объект
Бүлэг 6.2-т эдгээр нэр томьёог товч дурдсан. Одоо тэдгээр нь бодит ажил болж байна.
Аз болоход dataclasses модульд бэлэн туслах функц байдаг.
python
import json
from dataclasses import dataclass, asdict
@dataclass
class Zarlaga:
ner: str
dun: int
angilal: str
z = Zarlaga("Ном", 15000, "боловсрол")
d = asdict(z)
print(d)
print(type(d))
print(json.dumps(d, ensure_ascii=False)){'ner': 'Ном', 'dun': 15000, 'angilal': 'боловсрол'}
<class 'dict'>
{"ner": "Ном", "dun": 15000, "angilal": "боловсрол"}asdict() нь dataclass-ыг DICTIONARY болгож хувиргалаа.
Тэр dictionary нь одоо ердийн Python dictionary — json.dumps() нь түүнийг амархан хөрвүүлж байна.
Нэр нь тодорхой: asdict = "as dict" = "dictionary болгож."
ensure_ascii=False -ыг мартаагүйг анзаараарай. Бүлэг 6.2-ын дүрэм хэвээрээ: монгол текст бүхий JSON-д ЗААВАЛ.
Одоо буцаах зам. Энд бэлэн функц БАЙХГҮЙ, гэхдээ шийдэл нь маш энгийн.
python
d = {"ner": "Ном", "dun": 15000, "angilal": "боловсрол"}
z = Zarlaga(**d)
print(z)
print(type(z))Zarlaga(ner='Ном', dun=15000, angilal='боловсрол')
<class '__main__.Zarlaga'>Zarlaga(**d) — энэ бол Бүлэг 3.3-ын хоёр од бичлэг!
Санаж байна уу? Тэнд бид ингэж хэлсэн:
"Функцийн ДУУДАЛТ дотор
**dictionaryнь ЗАДАЛНА — key-value хосыг keyword аргумент болгож дэлгэнэ."
Тэгэхээр Zarlaga(**d) нь ЯГ дараах кодтой ижил утгатай:
python
Zarlaga(ner="Ном", dun=15000, angilal="боловсрол")Dictionary-гийн key-үүд нь параметрийн нэрс болж, value-ууд нь утгууд болж байна.
Энэ л шалтгаанаар key-үүд нь талбаруудын нэртэй ЯГ ТААРАХ ёстой. Хэрэв таарахгүй бол:
python
d = {"ner": "Ном", "dun": 15000, "kategori": "боловсрол"} # angilal биш!
z = Zarlaga(**d)TypeError: Zarlaga.__init__() got an unexpected keyword argument 'kategori'got an unexpected keyword argument 'kategori' — Бүлэг 3.2-оос танил алдаа. Zarlaga -д kategori гэсэн параметр байхгүй.
Гурван бүлгийн мэдлэг (3.2, 3.3, 9.1) нэг мөрөнд нийллээ.
Одоо бүтэн зураг: объектуудыг файлд хадгалж, буцааж уншья.
python
import json
from dataclasses import dataclass, asdict
@dataclass
class Zarlaga:
ner: str
dun: int
angilal: str = "бусад"
def khadgalakh(zam: str, zarlaguud: list[Zarlaga]) -> None:
uguudul = [asdict(z) for z in zarlaguud]
with open(zam, "w", encoding="utf-8") as f:
json.dump(uguudul, f, ensure_ascii=False, indent=2)
def achaalakh(zam: str) -> list[Zarlaga]:
try:
with open(zam, "r", encoding="utf-8") as f:
uguudul = json.load(f)
except FileNotFoundError:
return []
except json.JSONDecodeError:
print("Файл эвдэрсэн байна.")
return []
return [Zarlaga(**d) for d in uguudul]
# Хадгалах
zarlaguud = [
Zarlaga("Ном", 15000, "боловсрол"),
Zarlaga("Автобус", 1000, "тээвэр"),
Zarlaga("Хоол", 8500, "хоол"),
]
khadgalakh("zarlaga.json", zarlaguud)
print("Хадгаллаа.")
# Ачаалах
unshsan = achaalakh("zarlaga.json")
print(f"Ачаалсан: {len(unshsan)} зарлага")
for z in unshsan:
print(f" {z}")
print()
print(f"Төрөл: {type(unshsan[0])}")
print(f"Нийт: {sum(z.dun for z in unshsan):,} төгрөг")Хадгаллаа.
Ачаалсан: 3 зарлага
Zarlaga(ner='Ном', dun=15000, angilal='боловсрол')
Zarlaga(ner='Автобус', dun=1000, angilal='тээвэр')
Zarlaga(ner='Хоол', dun=8500, angilal='хоол')
Төрөл: <class '__main__.Zarlaga'>
Нийт: 24,500 төгрөгБүх зүйл ажиллаж байна.
zarlaga.json файлыг нээж хараарай:
json
[
{
"ner": "Ном",
"dun": 15000,
"angilal": "боловсрол"
},
{
"ner": "Автобус",
"dun": 1000,
"angilal": "тээвэр"
},
{
"ner": "Хоол",
"dun": 8500,
"angilal": "хоол"
}
]Ердийн JSON. Ямар ч онцгой зүйл алга. Тэр файлыг өөр программ (JavaScript, Java) уншиж чадна.
Хоёр гол мөрийг анхааралтай хараарай.
Хадгалахад:
python
uguudul = [asdict(z) for z in zarlaguud]Comprehension (Бүлэг 2.1) нь объект бүрийг dictionary болгож хувиргаж байна. Үр дүн нь list[dict] — JSON-ы байгалийн хэлбэр.
Ачаалахад:
python
return [Zarlaga(**d) for d in uguudul]Comprehension нь dictionary бүрийг объект болгож хувиргаж байна. Үр дүн нь list[Zarlaga] — Python-ы цэвэрхэн хэлбэр.
Хоёр comprehension, хоёр чиглэл. Тэдгээр нь бүхэл гүүрийг барьж байна.
Мөн анзаараарай: sum(z.dun for z in unshsan) — файлаас уншсан объектууд дээр z.dun гэж хандаж байна, z["dun"] биш. int(...) хувиргалт БАЙХГҮЙ. Editor нь бүрэн тусалж байна.
Бүлэг 6.5-ийн зарлагын бүртгэлийн БҮХ асуудал шийдэгдлээ.
Одоо илүү нарийн тохиолдол. Хэрэв dataclass дотор ӨӨР dataclass байвал?
python
import json
from dataclasses import dataclass, asdict
@dataclass
class Khayag:
duureg: str
khoroo: int
@dataclass
class Gishuun:
id: int
ner: str
khayag: Khayag
g = Gishuun(1001, "Болд", Khayag("Баянгол", 5))
d = asdict(g)
print(d)
print(json.dumps(d, ensure_ascii=False, indent=2)){'id': 1001, 'ner': 'Болд', 'khayag': {'duureg': 'Баянгол', 'khoroo': 5}}
{
"id": 1001,
"ner": "Болд",
"khayag": {
"duureg": "Баянгол",
"khoroo": 5
}
}asdict() нь ГҮНЗГИЙ ажилладаг! Дотоод Khayag объектыг ч бас dictionary болгосон.
Тэр нь маш ухаалаг. Хэдэн ч давхарга байсан — бүгдийг зөв хөрвүүлнэ.
Гэвч БУЦАХ зам нь АЖИЛЛАХГҮЙ:
python
d = {
"id": 1001,
"ner": "Болд",
"khayag": {"duureg": "Баянгол", "khoroo": 5},
}
g = Gishuun(**d)
print(g)
print(type(g.khayag))Gishuun(id=1001, ner='Болд', khayag={'duureg': 'Баянгол', 'khoroo': 5})
<class 'dict'>Анзаараарай: g.khayag нь DICTIONARY, Khayag объект БИШ!
Алдаа гарсангүй, программ ажиллаж байна. Гэвч буруу. Хэрэв та g.khayag.duureg гэж хандвал:
python
print(g.khayag.duureg)AttributeError: 'dict' object has no attribute 'duureg''dict' object has no attribute 'duureg' — dictionary-д .duureg гэж хандаж болохгүй, зөвхөн ["duureg"].
Яагаад ингэж байна вэ? Учир нь Gishuun(**d) нь зөвхөн ГАДНА талын dictionary-г задалсан. Дотоод dictionary нь БАЙГААГААРАА дамжсан. Python нь түүнийг Khayag болгож хувиргах ёстой гэдгийг МЭДЭХГҮЙ.
asdict() нь гүнзгий ажилладаг, гэвч эсрэг зам нь АЖИЛЛАХГҮЙ. Тэр нь тэгш хэмтэй БИШ.
Шийдэл: гараар угсрах.
python
def gishuun_uusgekh(d: dict) -> Gishuun:
khayag = Khayag(**d["khayag"])
return Gishuun(id=d["id"], ner=d["ner"], khayag=khayag)
g = gishuun_uusgekh(d)
print(g)
print(g.khayag.duureg)Gishuun(id=1001, ner='Болд', khayag=Khayag(duureg='Баянгол', khoroo=5))
Болд...Түр зогсъё — сүүлийн мөр нь Баянгол хэвлэх ёстой, Болд биш. Зөв гаралт:
Gishuun(id=1001, ner='Болд', khayag=Khayag(duureg='Баянгол', khoroo=5))
БаянголОдоо зөв. Дотоод объектыг ЭХЛЭЭД угсарч, дараа нь гадна объектод дамжуулж байна.
Энэ бол dataclass-ын ХЯЗГААР. Үүрлэсэн бүтэц нь гараар угсрахыг шаарддаг.
from_dict classmethodДээрх функц нь ажиллана, гэхдээ түүнийг class-д ХАМААРУУЛАХ нь илүү цэвэрхэн.
python
from dataclasses import dataclass, asdict
@dataclass
class Khayag:
duureg: str
khoroo: int
@dataclass
class Gishuun:
id: int
ner: str
khayag: Khayag
@classmethod
def from_dict(cls, d: dict) -> "Gishuun":
return cls(
id=d["id"],
ner=d["ner"],
khayag=Khayag(**d["khayag"]),
)
def to_dict(self) -> dict:
return asdict(self)
d = {
"id": 1001,
"ner": "Болд",
"khayag": {"duureg": "Баянгол", "khoroo": 5},
}
g = Gishuun.from_dict(d)
print(g)
print(g.khayag.duureg)
print(g.to_dict())Gishuun(id=1001, ner='Болд', khayag=Khayag(duureg='Баянгол', khoroo=5))
Баянгол
{'id': 1001, 'ner': 'Болд', 'khayag': {'duureg': 'Баянгол', 'khoroo': 5}}Хоёр шинэ зүйл гарч ирлээ.
@classmethod — өөр нэг decorator. Тэр нь "энэ method нь ОБЪЕКТОД биш, CLASS -д хамаарна" гэсэн утгатай.
Ялгааг харъя:
python
g = Gishuun.from_dict(d) # CLASS дээр дуудаж байна — объект хэрэггүй
d = g.to_dict() # ОБЪЕКТ дээр дуудаж байнаfrom_dict нь ОБЪЕКТ ҮҮСГЭХ функц. Тэгэхээр объект байхгүй үед дуудагдана — тиймээс тэр нь class дээр дуудагдах ёстой.
cls — self -ийн class хувилбар. self нь "энэ объект", cls нь "энэ class". cls(...) гэж дуудахад шинэ объект үүснэ — яг л Gishuun(...) гэж бичсэнтэй ижил.
Яагаад Gishuun(...) гэж шууд бичихгүй байна вэ? Учир нь cls нь inheritance-тэй зөв ажилладаг. Хэрэв хэн нэгэн Gishuun -ээс өвлөвөл, from_dict нь автоматаар ЗӨВ class-ыг үүсгэнэ.
-> "Gishuun" — хашилтанд байгааг анзаараарай. Яагаад?
Учир нь class-ын ДОТОР байхад Gishuun нэр хараахан бүрэн тодорхойлогдоогүй байна. Python нь түүнийг мэдэхгүй. Хашилт нь "энэ нэрийг ДАРАА нь шийд" гэсэн заавар юм.
(Python 3.11-ээс from typing import Self гэж import хийж, -> Self гэж бичих боломж бий — тэр нь илүү цэвэрхэн. Гэхдээ хашилттай хувилбар нь хаана ч ажилладаг тул би түүнийг ашиглана.)
Энэ хэв маягийг санаж яваарай. from_dict ба to_dict нь мэргэжлийн Python кодод маш түгээмэл. Тэдгээр нь гүүрийг class-д ӨӨРТ НЬ хамааруулж байна — тэр нь Бүлэг 7.3-ын сургамжтай ижил санаа: "мэдлэг нь өөрийн class-д амьдарна."
Одоо бодит амьдралын асуудал. Файл дахь өгөгдөл БУРУУ байж болно.
python
import json
from dataclasses import dataclass, asdict
@dataclass(frozen=True)
class Zarlaga:
ner: str
dun: int
angilal: str = "бусад"
def __post_init__(self) -> None:
if not self.ner.strip():
raise ValueError("Нэр хоосон байж болохгүй")
if self.dun <= 0:
raise ValueError(f"Дүн эерэг байх ёстой: {self.dun}")
def achaalakh(zam: str) -> list[Zarlaga]:
try:
with open(zam, "r", encoding="utf-8") as f:
uguudul = json.load(f)
except FileNotFoundError:
return []
except json.JSONDecodeError as alda:
print(f"Файл эвдэрсэн: {alda}")
return []
zarlaguud: list[Zarlaga] = []
for i, d in enumerate(uguudul, start=1):
try:
zarlaguud.append(Zarlaga(**d))
except (TypeError, ValueError) as alda:
print(f"Бичлэг {i} алгаслаа: {alda}")
return zarlaguudОдоо ЗОРИУДААР бохир файл үүсгэе. zarlaga.json:
json
[
{"ner": "Ном", "dun": 15000, "angilal": "боловсрол"},
{"ner": "", "dun": 5000, "angilal": "бусад"},
{"ner": "Автобус", "dun": -1000, "angilal": "тээвэр"},
{"ner": "Хоол", "dun": 8500, "kategori": "хоол"},
{"ner": "Кофе", "dun": 6000}
]Ажиллуулъя:
python
zarlaguud = achaalakh("zarlaga.json")
print(f"\nАчаалсан: {len(zarlaguud)} зарлага")
for z in zarlaguud:
print(f" {z}")Бичлэг 2 алгаслаа: Нэр хоосон байж болохгүй
Бичлэг 3 алгаслаа: Дүн эерэг байх ёстой: -1000
Бичлэг 4 алгаслаа: Zarlaga.__init__() got an unexpected keyword argument 'kategori'
Ачаалсан: 2 зарлага
Zarlaga(ner='Ном', dun=15000, angilal='боловсрол')
Zarlaga(ner='Кофе', dun=6000, angilal='бусад')Гурван бохир бичлэг хаягдлаа, программ унасангүй.
Кодыг задалъя.
__post_init__ нь ШАЛГАЛТ хийж байна (Бүлэг 9.2-оос). Буруу утгатай объект ОГТ үүсэхгүй.
except (TypeError, ValueError) нь ХОЁР төрлийн алдааг барьж байна:
ValueError — __post_init__ -ийн шалгалт унасан (хоосон нэр, сөрөг дүн)
TypeError — dictionary-гийн key нь талбартай таарахгүй (kategori), эсвэл шаардлагатай талбар дутуу
Хоёуланг нь нэг блокт барьж, бичлэгийг алгасаж байна.
enumerate(uguudul, start=1) (Бүлэг 2.3) нь бичлэгийн дугаарыг өгч байна — хэрэглэгчид АЛЬ бичлэг асуудалтай болохыг хэлж байна.
Сүүлчийн бичлэг (Кофе) нь angilal -гүй ч ажилласан — учир нь тэр нь default утгатай ("бусад").
Энэ бол Бүлэг 6.4-ийн "цэвэрлэх давхарга" -гийн ХАМААГҮЙ ЦЭВЭРХЭН хувилбар юм.
Тэнд бид гараар бүх шалгалт бичсэн: .get(), .strip(), int() + try/except, if not ner: return None. Хорь гаруй мөр.
Одоо class ӨӨРӨӨ өөрийгөө хамгаалж байна. Шалгалт нь __post_init__ -д амьдарч, TypeError нь автоматаар ирж байна.
Одоо би дээрх кодыг өөр нүдээр хараарай гэж хүсэж байна.
Юу болж байна вэ?
Гаднаас JSON ирж байна
Тэр нь Python-ы dictionary болж хувирч байна
Дараа нь dataclass болж хувирч байна
Хувирах явцад ШАЛГАЛТ ажиллаж байна
Буруу өгөгдөл нь АЛДАА үүсгэж байна
Зөв өгөгдөл нь type hint-тэй объект болж байна
Бүлэг 15-д FastAPI нь ЯГ ЭНЭ АЖЛЫГ хийнэ — ЗӨВХӨН АВТОМАТААР.
Та зөвхөн class бичнэ:
python
from pydantic import BaseModel
class Zarlaga(BaseModel):
ner: str
dun: int
angilal: str = "бусад"Дараа нь FastAPI нь:
Интернэтээс ирсэн JSON -ыг АВТОМАТААР задална
Type hint -ийн дагуу АВТОМАТААР шалгана
Буруу бол АВТОМАТААР алдаа буцаана (тодорхой мессежтэй)
Зөв бол таны функцэд бэлэн объект дамжуулна
Та json.load(), Zarlaga(**d), try/except, __post_init__ — ЮУ Ч бичихгүй.
Гэвч тэр бүхэн ажиллаж байна. Учир нь Pydantic нь ЯГ ТЭР кодыг таны type hint дээр үндэслэн автоматаар бичиж байна.
Тэгэхээр энэ хичээл нь юуны төлөө байсан бэ?
Учир нь FastAPI-г ойлгохын тулд, түүний хийж байгаа ажлыг ГАРААР нэг удаа хийж үзэх ЁСТОЙ. Тэгвэл тэр нь илбэ биш, харин таны бичих байсан кодыг автоматаар бичдэг хэрэгсэл гэдгийг мэдэх болно.
Бүлэг 15-д та /docs хуудсыг нээхэд гайхах болно. Гэхдээ та ЯАГААД гайхаж байгаагаа мэдэж байх болно.
Хэрэв сонирхвол: дээрх бүрэн мөчлөгийн программыг ажиллуулж, zarlaga.json файлыг ГАРААР засаад (шинэ зарлага нэмээд, эсвэл эвдээд), программаа дахин ажиллуулаарай. Шалгалт хэрхэн ажиллаж байгааг өөрийн нүдээр хараарай.
Дараа нь dun -ыг string болгож бичээд үзээрэй ("dun": "15000"). Юу болох вэ?
json
{"ner": "Тест", "dun": "15000"}Гэнэтийн зүйл: АЖИЛЛАНА. Учир нь dataclass нь type hint-ийг ШАЛГАДАГГҮЙ (Бүлэг 4.1-ийн гол сургамж!). Тэр нь "15000" гэсэн string-ийг dun талбарт эелдэгээр хийнэ.
Дараа нь sum(z.dun for z in zarlaguud) дуудахад:
TypeError: unsupported operand type(s) for +: 'int' and 'str'Энэ бол dataclass-ын ХЯЗГААР. Тэр нь бүтцийг үүсгэдэг, гэхдээ ТӨРЛИЙГ шалгадаггүй.
Pydantic нь шалгадаг. Тэр нь "15000" -ийг харвал АВТОМАТААР 15000 болгож хувиргана. Эсвэл "тэнэг" байвал тодорхой алдаа буцаана.
Тэр бол Pydantic-ийн жинхэнэ давуу тал. Бүлэг 15-д та түүнийг өөрийн нүдээр харна.
1. Объектыг шууд JSON болгох
TypeError: Object of type Zarlaga is not JSON serializableasdict(z) -ээр эхлээд dictionary болго.
2. asdict -ыг import мартах
NameError: name 'asdict' is not definedfrom dataclasses import dataclass, asdict.
3. Үүрлэсэн объектыг **d -ээр угсрах
python
g = Gishuun(**d)
print(g.khayag.duureg)AttributeError: 'dict' object has no attribute 'duureg'Дотоод объект нь dictionary хэвээрээ. Гараар угсра: Khayag(**d["khayag"]).
4. Key нь талбартай таарахгүй
TypeError: Zarlaga.__init__() got an unexpected keyword argument 'kategori'JSON-ы key-үүд нь dataclass-ын талбарын нэртэй ЯГ таарах ёстой. Эсвэл try/except TypeError -ээр барь.
5. Шаардлагатай талбар дутуу
json
{"dun": 15000}TypeError: Zarlaga.__init__() missing 1 required positional argument: 'ner'ner нь default-гүй тул ЗААВАЛ байх ёстой. Хэрэв заримдаа дутуу байж болох бол — default утга өг.
6. Type hint нь шалгалт хийнэ гэж бодох
json
{"ner": "Тест", "dun": "15000"}Ажиллана! dataclass нь төрлийг ШАЛГАДАГГҮЙ. Бүлэг 4.1-ийн гол сургамж хэвээрээ. Хэрэв шалгалт хэрэгтэй бол — __post_init__ -д гараар бич, эсвэл Pydantic ашигла (Бүлэг 15).
Dataclass-ыг шууд JSON болгож болохгүй → TypeError: Object of type X is not JSON serializable. JSON-д class байхгүй.
asdict(objekt) — dataclass → dictionary. ГҮНЗГИЙ ажиллана (үүрлэсэн dataclass-ыг ч хувиргана).
Zarlaga(**d) — dictionary → dataclass. Бүлэг 3.3-ын хоёр од нь key-value хосыг keyword аргумент болгож задалж байна.
Гүүр нь тэгш хэмтэй БИШ: asdict нь гүнзгий ажилладаг, **d нь ЗӨВХӨН гадна давхаргыг задалдаг. Үүрлэсэн объектыг ГАРААР угсра.
Стандарт хэв маяг:
Хадгалах: [asdict(z) for z in zarlaguud] → json.dump(...)
Ачаалах: json.load(...) → [Zarlaga(**d) for d in uguudul]
@classmethod + from_dict/to_dict — гүүрийг class-д өөрт нь хамааруулах цэвэрхэн хэв маяг. cls нь self -ийн class хувилбар.
__post_init__ + try/except (TypeError, ValueError) — бохир өгөгдлөөс хамгаалах. Class ӨӨРӨӨ өөрийгөө хамгаална. Бүлэг 6.4-ийн "цэвэрлэх давхарга" -гийн хамаагүй цэвэрхэн хувилбар.
Dataclass нь ТӨРЛИЙГ ШАЛГАДАГГҮЙ. {"dun": "15000"} нь эелдэгээр хүлээн авагдаж, дараа нь TypeError үүсгэнэ. Бүлэг 4.1-ийн сургамж хэвээрээ.
ХАМГИЙН ЧУХАЛ: энэ хичээлд бид ГАРААР хийсэн бүх ажил — JSON задлах, объект угсрах, шалгах, алдаа буцаах — FastAPI/Pydantic нь АВТОМАТААР хийдэг. Мөн тэр нь төрлийг ч бас шалгаж, хувиргадаг. Та түүнийг Бүлэг 15-д харах бөгөөд одоо түүний ард ЮУ байгааг мэдэж байна.
Дараагийн хичээлээр Түвшин 3 дуусна. Бид номын сангийн систем бичнэ: Zuil эцэг class ба Nom, Setguul, DVD хүү class-ууд (inheritance, Бүлэг 7), __str__ ба __eq__ (special methods, Бүлэг 8), Gishuun ба NomiinSan (dataclass, composition), JSON-д хадгалагдана (энэ хичээл). Тэр бол Түвшин 3-ын БҮХ мэдлэгийг нэг дор ажиллуулах жинхэнэ программ юм.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.