Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. YAML asoslari
- 2.2. YAML turlarni "taxmin qiladi"
- 2.3. Blok skalyarlar
- 2.4. YAML xavfsizligi
- 2.5. Anchor va merge
- 2.6. TOML — qat'iy va aniq
- 2.7. TOML xususiyatlari
- 2.8. Qaysi birini qachon
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — YAML turlari va tuzoqlari
- Misol 2 — YAML xavfsizlik, dump va anchor
- Misol 3 — TOML: qat'iy turlar va tuzilma
- Misol 4 — Amaliy: sozlamani yuklovchi va tekshiruvchi
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
16.6-dars: YAML va TOML
16-QISM — MA'LUMOT FORMATLARI · 6-dars
1. Kirish va motivatsiya
JSON mashinalar orasida ajoyib, lekin odam yozadigan sozlama uchun noqulay: qo'shtirnoqlar, vergullar, izohlar yo'q. Shuning uchun konfiguratsiya uchun ikki format tug'ildi: YAML (Docker Compose, Kubernetes, CI/CD, Ansible) va TOML (pyproject.toml, cargo, ko'p Python vositasi).
Ikkalasi ham "odam uchun qulay" deb ataladi, lekin ular butunlay boshqacha falsafaga ega — va YAML ning "qulayligi" mashhur tuzoqlar keltirib chiqaradi.
Real vaziyat. Bir jamoa Kubernetes sozlamasini YAML da yozardi. Uch alohida voqea:
- Mamlakatlar ro'yxatida
- NO(Norvegiya) yozildi — YAML uniFalsedeb o'qidi. Bu haqiqiy, mashhur "Norway problem". - Versiya raqami
version: 1.10yozildi — YAML uni1.1(float) qildi, oxirgi nol yo'qoldi. - Feature flag
enabled: yesyozildi — kimdir uni"yes"(satr) deb kutdi, YAML esaTrueqildi.
Boshqa loyihada pyproject.toml da bog'liqlik versiyasi bilan muammo bo'ldi — bu safar TOML qat'iy turlari tufayli xato darhol, aniq joyda ko'rindi.
Bu darsda YAML va TOML ni, ularning tuzoqlarini va qaysi birini qachon tanlashni o'rganamiz.
Bu darsda:
- YAML:
safe_load, tuzilma, blok skalyarlar - YAML tuzoqlari:
yes/no, Norway, sexagesimal, versiya - Xavfsizlik:
safe_loadvsload - YAML anchor va merge (
<<) - TOML:
tomllib(o'qish),tomli_w(yozish), qat'iy turlar - TOML:
nullyo'q, takroriy kalit xatosi - Amaliy: sozlamani yuklovchi va tekshiruvchi
- YAML vs TOML vs JSON — qachon qaysi biri
ℹ
PyYAMLvatomli_w— tashqi kutubxonalar (pip install pyyaml tomli_w).tomllib— Python 3.11+ standart kutubxonasida, lekin faqat o'qish uchun.
2. Nazariya — chuqur tushuntirish
2.1. YAML asoslari
YAML — chekinish (bo'shliq) bilan tuzilmani ifodalaydi, qo'shtirnoq va vergul shart emas:
loyiha: Wisar
port: 8000
teglar:
- python
- web
baza:
host: localhost
port: 5432import yaml
malumot = yaml.safe_load(matn) # ⭐ har doim safe_load
matn = yaml.safe_dump(malumot, allow_unicode=True, sort_keys=False)| Xususiyat | Izoh |
|---|---|
| Chekinish | Ichma-ichlikni bildiradi ( TAB emas, bo'shliq) |
- |
Ro'yxat elementi |
kalit: qiymat |
Lug'at |
# |
Izoh |
| blok |
Yangi qatorlar saqlanadi |
> folded |
Yangi qatorlar bo'shliqqa aylanadi |
2.2. YAML turlarni "taxmin qiladi"
Bu YAML ning eng katta muammosi. PyYAML YAML 1.1 ni qo'llaydi va qo'shtirnoqsiz qiymatlarning turini o'zi aniqlaydi:
| Yozilgan | YAML o'qiydi |
|---|---|
yes, on, true, True, TRUE |
True (bool) |
no, off, false |
False (bool) |
NO |
False — Norway problem (Norvegiya kodi) |
1.10 |
1.1 (float) — oxirgi nol yo'qoladi |
22:22 |
1342 (sexagesimal — 22×60+22) |
2026-09-17 |
datetime.date |
null, ~ |
None |
0o17, 0xFF |
oktal/o'n oltilik son |
Yechim: qiymatni qo'shtirnoqqa oling — "NO", "1.10", "yes" — shunda satr bo'lib qoladi.
2.3. Blok skalyarlar
literal: |
birinchi qator
ikkinchi qator
folded: >
bu uzun matn
bitta qatorga birlashadi| Belgi | Natija |
|---|---|
| |
"birinchi qator\nikkinchi qator\n" — yangi qatorlar saqlanadi |
> |
"bu uzun matn bitta qatorga birlashadi\n" — bo'shliqqa aylanadi |
2.4. YAML xavfsizligi
YAML nafaqat ma'lumot, balki Python obyektlarini ham ifodalashi mumkin: !!python/object/apply:os.system. Oddiy yaml.load bularni bajaradi — bu pickle kabi masofadan kod bajarish xavfi.
yaml.load(ishonchsiz) # ❌ kod bajarishi mumkin
yaml.safe_load(ishonchsiz) # ✅ faqat oddiy turlar; xavfli teg → ConstructorError Har doim safe_load va safe_dump. yaml.load ni faqat Loader= bilan va faqat o'zingiz yozgan ma'lumot uchun ishlating.
2.5. Anchor va merge
YAML takrorni kamaytirish uchun anchor (&), havola (*) va merge (<<) beradi:
default: &def
timeout: 30
retry: 3
servis_a:
<<: *def
host: a.localservis_a → {timeout: 30, retry: 3, host: a.local}. Anchor lar takror kengayishi (YAML "billion laughs") xavfini ham keltiradi — ishonchsiz YAML da ehtiyot bo'ling.
2.6. TOML — qat'iy va aniq
TOML ("Tom's Obvious Minimal Language") YAML ning aksi: aniq, qat'iy turlar, taxmin yo'q.
loyiha = "Wisar"
versiya = "1.2.0" # satr — qo'shtirnoq majburiy
port = 8000 # int
narx = 45000.50 # float
faol = true # bool — faqat true/false
teglar = ["python", "web"]
sana = 2026-09-17 # native date
[baza] # jadval (table) = lug'at
host = "localhost"
port = 5432
[baza.pool] # ichma-ich jadval
max = 10
[[servislar]] # jadvallar massivi = lug'atlar ro'yxati
nom = "api"
[[servislar]]
nom = "worker"import tomllib
with open("config.toml", "rb") as f: # ⚠️ binar rejim
malumot = tomllib.load(f)
malumot = tomllib.loads(matn) # satrdan| TOML tuzilishi | Python |
|---|---|
[jadval] |
ichma-ich dict |
[[massiv]] |
list[dict] |
sana, vaqt |
date, datetime (native) |
1_000_000 |
1000000 (pastki chiziq) |
2.7. TOML xususiyatlari
| Xususiyat | Izoh |
|---|---|
null yo'q |
TOML da bo'sh qiymat yo'q — kalitni umuman yozmang |
| Takroriy kalit | TOMLDecodeError — YAML/JSON dan farqli, xato |
| Satr — faqat qo'shtirnoqda | versiya = 1.2.0 xato; "1.2.0" to'g'ri |
tomllib — faqat o'qish |
Yozish uchun tomli_w yoki tomlkit |
tomllib.load — bytes |
Faylni "rb" rejimida oching |
parse_float=Decimal |
JSON kabi aniqlik nazorati |
TOML ning qat'iyligi — kuchli tomoni: xatolar konfiguratsiya yozilishida darhol topiladi, ishga tushganda emas.
2.8. Qaysi birini qachon
| Format | Eng yaxshi |
|---|---|
| TOML | Loyiha sozlamasi, vosita konfiguratsiyasi (pyproject.toml), tekis-o'rtacha tuzilma |
| YAML | Chuqur ichma-ich, ko'p qatorli (Kubernetes, CI/CD, Ansible) — lekin tuzoqlarga ehtiyot |
| JSON | Mashinalararo almashinuv, API |
| .env | Oddiy KALIT=qiymat sirlar |
3. Tez ma'lumotnoma
import yaml, tomllib
malumot = yaml.safe_load(yaml_matn) # ⭐ safe_load
yaml.safe_dump(malumot, allow_unicode=True, sort_keys=False)
with open("config.toml", "rb") as f: # ⚠️ binar
sozlama = tomllib.load(f)
sozlama = tomllib.loads(toml_matn, parse_float=decimal.Decimal)
import tomli_w # yozish (tashqi)
tomli_w.dump(malumot, open("out.toml", "wb"))Qoidalar
YAML: har doim safe_load / safe_dump
YAML: yes/no/NO/1.10 — qo'shtirnoqqa oling
YAML: chekinish bo'shliq bilan, TAB emas
TOML: satr qo'shtirnoqda, faqat true/false
TOML: tomllib faqat o'qiydi, "rb" rejim
sozlama uchun: TOML (tekis), YAML (chuqur), JSON emas4. Batafsil misollar
Misol 1 — YAML turlari va tuzoqlari
"""safe_load; turlar taxmini: yes/no/on/off, Norway problem, sexagesimal, versiya, date; qo'shtirnoq bilan yechim; blok skalyarlar (| va >)."""
import yaml
SOZLAMA = """
loyiha: Wisar
versiya: 1.10
faol: yes
debug: off
port: 8000
narx: 45000.50
teglar:
- python
- web
mamlakatlar: [NO, SE, FI]
vaqt_belgi: 22:22
sana: 2026-09-17
literal: |
birinchi qator
ikkinchi qator
folded: >
bu uzun matn
bitta qatorga birlashadi
"""
def main() -> None:
d = yaml.safe_load(SOZLAMA)
print("=== 1. ⚠️ Turlar taxmini ===")
for kalit in ("versiya", "faol", "debug", "port", "narx", "sana"):
print(f" {kalit:9} = {d[kalit]!r:24} ({type(d[kalit]).__name__})")
print("\n=== 2. ⚠️ Norway problem ===")
print(f" mamlakatlar: [NO, SE, FI] → {d['mamlakatlar']}")
print(f" ⚠️ NO (Norvegiya) → {d['mamlakatlar'][0]} (bool!), SE va FI — satr")
print("\n=== 3. ⚠️ Boshqa tuzoqlar ===")
print(f" versiya 1.10 → {d['versiya']!r} ← oxirgi nol yo'qoldi (float)")
print(f" 22:22 → {d['vaqt_belgi']!r} ← sexagesimal: 22×60+22")
print(f" yes → {d['faol']}, off → {d['debug']} ← bool, satr emas")
print("\n=== 4. ⭐ Yechim: qo'shtirnoq ===")
toza = yaml.safe_load("""
versiya: "1.10"
mamlakatlar: ["NO", "SE", "FI"]
faol: "yes"
""")
print(f" versiya: {toza['versiya']!r} ({type(toza['versiya']).__name__})")
print(f" mamlakatlar: {toza['mamlakatlar']}")
print(f" faol: {toza['faol']!r} ({type(toza['faol']).__name__})")
print("\n=== 5. Blok skalyarlar ===")
print(f" literal (|): {d['literal']!r}")
print(f" folded (>): {d['folded']!r}")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. ⚠️ Turlar taxmini ===
versiya = 1.1 (float)
faol = True (bool)
debug = False (bool)
port = 8000 (int)
narx = 45000.5 (float)
sana = datetime.date(2026, 9, 17) (date)
=== 2. ⚠️ Norway problem ===
mamlakatlar: [NO, SE, FI] → [False, 'SE', 'FI']
⚠️ NO (Norvegiya) → False (bool!), SE va FI — satr
=== 3. ⚠️ Boshqa tuzoqlar ===
versiya 1.10 → 1.1 ← oxirgi nol yo'qoldi (float)
22:22 → 1342 ← sexagesimal: 22×60+22
yes → True, off → False ← bool, satr emas
=== 4. ⭐ Yechim: qo'shtirnoq ===
versiya: '1.10' (str)
mamlakatlar: ['NO', 'SE', 'FI']
faol: 'yes' (str)
=== 5. Blok skalyarlar ===
literal (|): 'birinchi qator\nikkinchi qator\n'
folded (>): 'bu uzun matn bitta qatorga birlashadi\n'Nima ko'rsatdi: 2.1, 2.2, 2.3-bo'limlar.
Misol 2 — YAML xavfsizlik, dump va anchor
"""safe_load xavfli tegni bloklaydi; safe_dump va allow_unicode; sort_keys; anchor, havola va merge (<<); ishonchsiz YAML da anchor kengayishi haqida eslatma."""
import yaml
def main() -> None:
print("=== 1. ⚠️ safe_load xavfsizligi ===")
xavfli = "!!python/object/apply:os.system ['echo hujum']"
try:
yaml.safe_load(xavfli)
except yaml.YAMLError as xato:
print(f" safe_load bloklaydi: {type(xato).__name__}")
print(" ⚠️ yaml.load(xavfli) esa buyruqni BAJARADI — hech qachon ishonchsizga yaml.load")
print("\n=== 2. safe_dump ===")
malumot = {"ism": "Oʻgʻiloy", "yosh": 25, "teglar": ["python", "web"], "faol": True}
print(" allow_unicode=False (sukut) — ASCII escape:")
for qator in yaml.safe_dump(malumot, sort_keys=True).splitlines():
print(f" {qator}")
print(" ⭐ allow_unicode=True, sort_keys=False:")
for qator in yaml.safe_dump(malumot, allow_unicode=True, sort_keys=False).splitlines():
print(f" {qator}")
print("\n=== 3. Anchor va merge ===")
konfig = """
default: &sukut
timeout: 30
retry: 3
log_level: info
servis_api:
<<: *sukut
host: api.local
servis_worker:
<<: *sukut
host: worker.local
retry: 5
"""
d = yaml.safe_load(konfig)
print(f" servis_api: {d['servis_api']}")
print(f" servis_worker: {d['servis_worker']} ← retry override qilindi")
print(" ⚠️ anchor lar ichma-ich takrorlansa kengayadi — ishonchsiz YAML da DoS xavfi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. ⚠️ safe_load xavfsizligi ===
safe_load bloklaydi: ConstructorError
⚠️ yaml.load(xavfli) esa buyruqni BAJARADI — hech qachon ishonchsizga yaml.load
=== 2. safe_dump ===
allow_unicode=False (sukut) — ASCII escape:
faol: true
ism: "O\u02BBg\u02BBiloy"
teglar:
- python
- web
yosh: 25
⭐ allow_unicode=True, sort_keys=False:
ism: Oʻgʻiloy
yosh: 25
teglar:
- python
- web
faol: true
=== 3. Anchor va merge ===
servis_api: {'timeout': 30, 'retry': 3, 'log_level': 'info', 'host': 'api.local'}
servis_worker: {'timeout': 30, 'retry': 5, 'log_level': 'info', 'host': 'worker.local'} ← retry override qilindi
⚠️ anchor lar ichma-ich takrorlansa kengayadi — ishonchsiz YAML da DoS xavfiNima ko'rsatdi: 2.4, 2.5-bo'limlar.
Misol 3 — TOML: qat'iy turlar va tuzilma
"""tomllib.loads/load; qat'iy turlar; native date/datetime; jadvallar va jadvallar massivi; pastki chiziqli sonlar; xatolar: takroriy kalit, null yo'q, satr qo'shtirnoqsiz; parse_float; tomli_w bilan yozish."""
import datetime
import io
import tomllib
from decimal import Decimal
import tomli_w
TOML = """# Wisar loyiha sozlamasi
loyiha = "Wisar"
versiya = "1.2.0"
port = 8000
narx = 45000.50
faol = true
katta = 1_000_000
teglar = ["python", "web"]
sana = 2026-09-17
vaqt = 2026-09-17T09:30:00+05:00
[baza]
host = "localhost"
port = 5432
[baza.pool]
min = 1
max = 10
[[servislar]]
nom = "api"
port = 8001
[[servislar]]
nom = "worker"
port = 8002
"""
def main() -> None:
d = tomllib.loads(TOML)
print("=== 1. ⭐ Qat'iy turlar ===")
for kalit in ("versiya", "port", "narx", "faol", "katta"):
print(f" {kalit:8} = {d[kalit]!r:14} ({type(d[kalit]).__name__})")
print(f" ⭐ versiya '1.2.0' — satr bo'lib qoladi (YAML dan farqli)")
print("\n=== 2. Native sana va vaqt ===")
print(f" sana: {d['sana']} ({type(d['sana']).__name__})")
print(f" vaqt: {d['vaqt']} mintaqa: {d['vaqt'].tzinfo}")
print("\n=== 3. Jadvallar va massivlar ===")
print(f" baza: {d['baza']}")
print(f" baza.pool.max: {d['baza']['pool']['max']}")
print(f" servislar (jadvallar massivi): {[s['nom'] for s in d['servislar']]}")
print("\n=== 4. ⚠️ Xatolar ===")
for nom, matn in [("takroriy kalit", "a = 1\na = 2"), ("null yo'q", "a = null"),
("qo'shtirnoqsiz satr", "versiya = 1.2.0")]:
try:
tomllib.loads(matn)
except tomllib.TOMLDecodeError as xato:
print(f" {nom:20}: TOMLDecodeError: {str(xato).split(' (')[0]}")
print("\n=== 5. parse_float va bytes ===")
d2 = tomllib.loads("narx = 0.1", parse_float=Decimal)
print(f" parse_float=Decimal: {d2['narx']!r}")
print(f" tomllib.load bytes: {tomllib.load(io.BytesIO(b'x = 42'))['x']}")
print("\n=== 6. tomli_w bilan yozish ===")
yangi = {"loyiha": "Wisar", "port": 8000, "faol": True,
"teglar": ["a", "b"], "baza": {"host": "localhost", "port": 5432}}
chiqish = tomli_w.dumps(yangi)
for qator in chiqish.splitlines():
print(f" {qator}")
print(f" aylanib qaytish teng: {tomllib.loads(chiqish) == yangi}")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. ⭐ Qat'iy turlar ===
versiya = '1.2.0' (str)
port = 8000 (int)
narx = 45000.5 (float)
faol = True (bool)
katta = 1000000 (int)
⭐ versiya '1.2.0' — satr bo'lib qoladi (YAML dan farqli)
=== 2. Native sana va vaqt ===
sana: 2026-09-17 (date)
vaqt: 2026-09-17 09:30:00+05:00 mintaqa: UTC+05:00
=== 3. Jadvallar va massivlar ===
baza: {'host': 'localhost', 'port': 5432, 'pool': {'min': 1, 'max': 10}}
baza.pool.max: 10
servislar (jadvallar massivi): ['api', 'worker']
=== 4. ⚠️ Xatolar ===
takroriy kalit : TOMLDecodeError: Cannot overwrite a value
null yo'q : TOMLDecodeError: Invalid value
qo'shtirnoqsiz satr : TOMLDecodeError: Expected newline or end of document after a statement
=== 5. parse_float va bytes ===
parse_float=Decimal: Decimal('0.1')
tomllib.load bytes: 42
=== 6. tomli_w bilan yozish ===
loyiha = "Wisar"
port = 8000
faol = true
teglar = [
"a",
"b",
]
[baza]
host = "localhost"
port = 5432
aylanib qaytish teng: TrueNima ko'rsatdi: 2.6, 2.7-bo'limlar.
Misol 4 — Amaliy: sozlamani yuklovchi va tekshiruvchi
Ilovamiz sozlamani TOML (asosiy) yoki YAML (muqobil) da qabul qiladi, uni sukut qiymatlar bilan ichma-ich birlashtiradi, sxema bo'yicha tekshiradi (turlar, majburiy maydonlar, oralik) va aniq xato beradi. Bu — YAML/TOML ni real ilovada to'g'ri ishlatish namunasi: format qat'iy o'qiladi, keyin qat'iy tekshiriladi.
"""TOML va YAML dan sozlama yuklash; ichma-ich birlashtirish; sxema tekshiruvi (tur, majburiylik, oraliq); format aniqlash; aniq xato xabarlari."""
import tomllib
from typing import Any
import yaml
SUKUT: dict[str, Any] = {
"server": {"host": "0.0.0.0", "port": 8000, "workers": 4},
"baza": {"host": "localhost", "port": 5432, "pool": {"min": 1, "max": 10}},
"log": {"level": "info"},
}
# (yo'l, tur, tekshiruv)
SXEMA = [
(("server", "port"), int, lambda v: 1 <= v <= 65535),
(("server", "workers"), int, lambda v: 1 <= v <= 64),
(("baza", "port"), int, lambda v: 1 <= v <= 65535),
(("baza", "pool", "max"), int, lambda v: v >= 1),
(("log", "level"), str, lambda v: v in {"debug", "info", "warning", "error"}),
]
def birlashtir(asos: dict, ustki: dict) -> dict:
natija = {k: (v.copy() if isinstance(v, dict) else v) for k, v in asos.items()}
for kalit, qiymat in ustki.items():
if isinstance(qiymat, dict) and isinstance(natija.get(kalit), dict):
natija[kalit] = birlashtir(natija[kalit], qiymat)
else:
natija[kalit] = qiymat
return natija
def yukla(matn: str, format: str) -> dict:
if format == "toml":
return tomllib.loads(matn)
if format == "yaml":
d = yaml.safe_load(matn)
if not isinstance(d, dict):
raise ValueError("sozlama lug'at bo'lishi kerak")
return d
raise ValueError(f"noma'lum format: {format}")
def ol(d: dict, yol: tuple):
for qism in yol:
d = d[qism]
return d
def tekshir(sozlama: dict) -> list[str]:
xatolar = []
for yol, tur, shart in SXEMA:
nom = ".".join(yol)
try:
qiymat = ol(sozlama, yol)
except (KeyError, TypeError):
xatolar.append(f"{nom}: maydon yo'q")
continue
if isinstance(qiymat, bool) or not isinstance(qiymat, tur):
xatolar.append(f"{nom}: {tur.__name__} kutilgan, {type(qiymat).__name__} keldi ({qiymat!r})")
elif not shart(qiymat):
xatolar.append(f"{nom}: qiymat oraliqdan tashqari ({qiymat!r})")
return xatolar
def main() -> None:
print("=== 1. TOML sozlama (qisman) ===")
toml_matn = """
[server]
port = 9000
workers = 8
[baza]
host = "db.example"
[log]
level = "debug"
"""
sozlama = birlashtir(SUKUT, yukla(toml_matn, "toml"))
print(f" server: {sozlama['server']}")
print(f" baza: {sozlama['baza']} ← host o'zgardi, pool sukutdan")
print(f" log: {sozlama['log']}")
print(f" tekshiruv: {tekshir(sozlama) or 'toza ✅'}")
print("\n=== 2. Xatoli sozlama ===")
yomon = """
[server]
port = 99999
workers = "ko'p"
[log]
level = "trace"
"""
sozlama = birlashtir(SUKUT, yukla(yomon, "toml"))
for xato in tekshir(sozlama):
print(f" ❌ {xato}")
print("\n=== 3. YAML muqobil (tuzoq bilan) ===")
yaml_matn = """
server:
port: 8080
workers: 4
log:
level: info
faol: yes
"""
d = yukla(yaml_matn, "yaml")
sozlama = birlashtir(SUKUT, d)
print(f" server.port: {sozlama['server']['port']}")
print(f" ⚠️ 'faol: yes' → {sozlama['faol']!r} ({type(sozlama['faol']).__name__}) — YAML tuzog'i")
print(f" tekshiruv: {tekshir(sozlama) or 'toza ✅'}")
print("\n=== 4. Xulosa ===")
print(" TOML — qat'iy turlar, xato darhol; YAML — moslashuvchan, lekin tuzoqli")
print(" ikkalasi ham: yuklashdan keyin sxema bilan tekshirish shart")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. TOML sozlama (qisman) ===
server: {'host': '0.0.0.0', 'port': 9000, 'workers': 8}
baza: {'host': 'db.example', 'port': 5432, 'pool': {'min': 1, 'max': 10}} ← host o'zgardi, pool sukutdan
log: {'level': 'debug'}
tekshiruv: toza ✅
=== 2. Xatoli sozlama ===
❌ server.port: qiymat oraliqdan tashqari (99999)
❌ server.workers: int kutilgan, str keldi ("ko'p")
❌ log.level: qiymat oraliqdan tashqari ('trace')
=== 3. YAML muqobil (tuzoq bilan) ===
server.port: 8080
⚠️ 'faol: yes' → True (bool) — YAML tuzog'i
tekshiruv: toza ✅
=== 4. Xulosa ===
TOML — qat'iy turlar, xato darhol; YAML — moslashuvchan, lekin tuzoqli
ikkalasi ham: yuklashdan keyin sxema bilan tekshirish shartNima ko'rsatdi: 2.1, 2.6, 2.8-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "YAML qiymatlarni satr qoldiradi" | yes, NO, 1.10, 22:22 — bool/float/int ga aylanadi |
"yaml.load xavfsiz" |
Kod bajaradi — safe_load ishlating |
| "TAB bilan chekinish mumkin" | YAML da faqat bo'shliq |
| "TOML versiyani float qiladi" | "1.2.0" — satr; TOML taxmin qilmaydi |
"TOML da null bor" |
Yo'q — kalitni umuman yozmang |
| "Takroriy kalit — oxirgisi olinadi" | TOML da TOMLDecodeError |
"tomllib yoza oladi" |
Faqat o'qiydi; yozish — tomli_w |
| "YAML har doim TOML dan yaxshi" | Chuqur tuzilma — YAML, tekis sozlama — TOML |
6. Keng tarqalgan xatolar va yechimlari
1. yaml.load ishonchsiz ma'lumotga
yaml.load(tashqi) # ❌ kod bajaradi
yaml.safe_load(tashqi) # ✅2. Norway / yes-no tuzog'i
mamlakat: NO # ❌ False
mamlakat: "NO" # ✅ satr
enabled: yes # ❌ True
enabled: "yes" # ✅ (yoki: enabled: true — haqiqiy bool)3. TOML faylni matn rejimida
tomllib.load(open("c.toml")) # ❌ TypeError (str keladi)
tomllib.load(open("c.toml", "rb")) # ✅ binar4. TOML da qo'shtirnoqsiz satr
versiya = 1.2.0 # ❌ TOMLDecodeError
versiya = "1.2.0" # ✅5. tomllib bilan yozishga urinish
tomllib.dumps(d) # ❌ AttributeError
tomli_w.dumps(d) # ✅6. YAML da TAB
kalit: qiymat # ❌ TAB — ParserError
kalit: qiymat # ✅ bo'shliq7. Sozlamani tekshirmasdan ishlatish
port = yaml.safe_load(matn)["port"] # ❌ tur/oraliq noma'lum
# ✅ yuklashdan keyin sxema tekshiruvi (Misol 4, yoki pydantic 13.8)8. YAML dan Unicode ni escape bilan yozish
yaml.safe_dump(d) # "Oʻ..." — o'qib bo'lmaydi
yaml.safe_dump(d, allow_unicode=True) # ✅ Oʻgʻiloy7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 13.8-dars (o'tilgan):
pydantic— sozlamani sxema bilan tekshirish (pydantic-settings) - 16.2-dars (o'tilgan): JSON — mashinalararo muqobil
- 16.4-dars (o'tilgan):
pickle/yaml.load— "ma'lumot bo'lgan kod" xavfi - 19-qism: paketlash —
pyproject.toml - 20-qism: FastAPI — sozlama boshqaruvi
- 28-qism: infratuzilma — Docker Compose, Kubernetes, CI/CD YAML
8. Eng yaxshi amaliyotlar
YAML — har doim
safe_load/safe_dump.YAML tuzoqli qiymatlarni (
yes/NO/1.10) qo'shtirnoqqa oling.Loyiha/vosita sozlamasi — TOML; chuqur infratuzilma — YAML.
TOML — satr qo'shtirnoqda, fayl
"rb"rejimda.Format nima bo'lishidan qat'i nazar — yuklashdan keyin sxema bilan tekshiring.
Sukut qiymatlar bilan ichma-ich birlashtiring.
YAML da chekinish — bo'shliq, hech qachon TAB.
Sirlar — sozlama faylida emas, muhit o'zgaruvchisi yoki maxfiy boshqaruvda.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
import yaml, tomllib
1. print(yaml.safe_load("x: yes")["x"])
2. print(yaml.safe_load("x: NO")["x"])
3. print(yaml.safe_load("x: 1.10")["x"])
4. print(yaml.safe_load('x: "yes"')["x"])
5. print(type(yaml.safe_load("x: 2026-09-17")["x"]).__name__)
6. print(yaml.safe_load("x: 22:22")["x"])
7. print(tomllib.loads('x = "1.2.0"')["x"])
8. print(type(tomllib.loads("x = 2026-09-17")["x"]).__name__)
9. print(tomllib.loads("x = 1_000")["x"])
10. print(tomllib.loads("[a]\nb = 1")["a"]["b"])
11. try:
tomllib.loads("a = 1\na = 2")
except tomllib.TOMLDecodeError:
print("xato")
12. print(yaml.safe_load("a: [1, 2]\nb: {x: 1}"))Javoblar
TrueFalse1.1yesdate13421.2.0date10001xato{'a': [1, 2], 'b': {'x': 1}}
Vazifa 2: Xatolarni tuzating
1. def yukla(matn):
return yaml.load(matn) # foydalanuvchi yuborgan
2. def toml_oqi(yol):
with open(yol) as f:
return tomllib.load(f)
3. # config.yaml:
# mamlakatlar: [NO, US, GB]
# versiya: 2.10
def oqi(yaml_matn):
d = yaml.safe_load(yaml_matn)
return d["mamlakatlar"], d["versiya"] # NO va 2.10 kutilgan
4. def saqla(yol, sozlama):
with open(yol, "w") as f:
tomllib.dump(sozlama, f)
5. def dump_yaml(malumot):
return yaml.safe_dump(malumot) # o'zbekcha matn borJavoblar
1. def yukla(matn):
return yaml.safe_load(matn) # kod bajarilmaydi
2. def toml_oqi(yol):
with open(yol, "rb") as f: # binar
return tomllib.load(f)
3. # YAML faylida tuzoqli qiymatlar qo'shtirnoqda bo'lishi kerak:
# mamlakatlar: ["NO", "US", "GB"]
# versiya: "2.10"
def oqi(yaml_matn):
d = yaml.safe_load(yaml_matn)
return d["mamlakatlar"], d["versiya"]
4. import tomli_w
def saqla(yol, sozlama):
with open(yol, "wb") as f: # tomli_w, binar
tomli_w.dump(sozlama, f)
5. def dump_yaml(malumot):
return yaml.safe_dump(malumot, allow_unicode=True, sort_keys=False)Vazifa 3: Format konvertori
konvert kirish.yaml chiqish.toml:
- YAML ↔ TOML ↔ JSON o'zaro (kengaytmadan format aniqlash)
- TOML da
nullyo'qligini hisobga oling:Nonemaydonlarni tushiring va ogohlantiring - YAML tuzoqlarini aniqlab ogohlantiring (
NO,yes,1.10kabi qiymatlar) - Aylanib qaytish testi: YAML → TOML → YAML semantik teng
Vazifa 4: pyproject.toml o'quvchi
[project]danname,version,dependenciesni ajrating[tool.*]bo'limlarini ro'yxatlang- Bog'liqlik spetsifikatsiyalarini (
paket>=1.0) tahlil qiling - Yo'q yoki noto'g'ri maydonlarni
qator:ustunbilan xabar qiling (TOMLDecodeError)
Vazifa 5: YAML tuzoq detektori
yaml_tekshir(matn) — quyidagilarni ogohlantirsin:
- Qo'shtirnoqsiz
yes/no/on/off/NOva shunga o'xshash qiymatlar - Oxirgi nolli versiya (
1.10), sexagesimal (22:22) - TAB bilan chekinish
- Har biriga qator raqami va tuzatilgan variant
Vazifa 6: Sozlama qatlamlari
- Uch qatlam: sukut (kod) →
config.toml→ muhit o'zgaruvchilari - Har qatlam oldingisini ichma-ich bekor qilsin (Misol 4 dagi
birlashtir) WISAR_SERVER__PORT=9000kabi o'zgaruvchilar ichma-ich yo'lga aylansin- Yakuniy sozlamani sxema bilan tekshiring (pydantic bilan solishtiring)
Vazifa 7: O'ylash
YAML "odam uchun eng qulay" format sifatida yaratildi, lekin bugun uni "1.5 milliard dollarlik xato" (Norway problem va boshqalar) deb tanqid qiladilar. TOML esa aynan YAML muammolariga javob sifatida yaratildi va Python pyproject.toml uchun uni tanladi. Nima uchun "qulaylik" murakkablik va tuzoqlar keltiradi, va TOML ning "zerikarli aniqligi" nega sozlama uchun afzallik?
Javob
Qisqa javob: YAML ning tuzoqlari "qulaylik" ning to'g'ridan-to'g'ri natijasi: qo'shtirnoqsiz yozishga ruxsat berish uchun YAML turni taxmin qilishi kerak, va har qanday taxmin ba'zan yanglishadi (NO → False). TOML aksincha — biroz ko'proq yozishni (qo'shtirnoq) talab qiladi, lekin hech narsani taxmin qilmaydi, shuning uchun tuzoqsiz. Sozlama fayllari kamdan-kam yoziladi, lekin ko'p o'qiladi va xatosi qimmatga tushadi — bu yerda "zerikarli aniqlik" xavfsizlikdan ustun.
1. Nega qulaylik murakkablik keltiradi
| YAML qulayligi | Narxi |
|---|---|
| Qo'shtirnoqsiz qiymat | Tur taxmini kerak → yanglish |
yes/no bool |
NO, mamlakat kodi bilan to'qnashadi |
| Chekinish tuzilma | TAB/bo'shliq, ko'rinmas xatolar |
| Anchor, merge, tag | Katta spetsifikatsiya, !!python xavfi |
| Ko'p yozish usuli | Bir narsani turlicha yozish mumkin |
2. Nega TOML "zerikarli aniqlik" afzal
| TOML tanlovi | Foyda |
|---|---|
| Satr — majburiy qo'shtirnoq | Taxmin yo'q, tuzoq yo'q |
Faqat true/false |
yes/NO chalkashligi yo'q |
| Takroriy kalit — xato | Jim xato yo'q |
| Kichik, aniq grammatika | Bir xil talqin |
| Native sana, son | Aniq turlar |
3. Sozlama fayli konteksti
| Xususiyat | Ta'siri |
|---|---|
| Kam yoziladi | Qo'shtirnoqning "noqulayligi" arzimas |
| Ko'p o'qiladi/yuklanadi | Aniqlik va bir xillik muhim |
| Xatosi qimmat | Ishlab chiqarishda buzilgan sozlama — jiddiy nosozlik |
| Odam va vosita o'qiydi | Ikkovi bir xil tushunishi kerak |
4. Har birining o'rni
| Format | Eng mos |
|---|---|
| TOML | Tekis/o'rtacha sozlama, vositalar (pyproject.toml) |
| YAML | Chuqur ichma-ich, ko'p qatorli (Kubernetes) — lekin qat'iy amaliyot bilan |
| JSON | Almashinuv, API |
5. Muhandislik saboqlari
- "Qulaylik" ko'pincha "kamroq belgi" degani — lekin belgi ma'no tashiydi
- Taxmin (implicit) qulay ko'rinadi, lekin chegara holatlarida yanglishadi
- Aniqlik (explicit) zerikarli, lekin ishonchli — kritik konfiguratsiyada afzal
- Format vazifaga mos bo'lsin; YAML ishlatilsa — tuzoqli qiymatlarni qo'shtirnoqda va qat'iy tekshiruv bilan
6. Xulosa
- YAML tuzoqlari — turni taxmin qilish zaruratidan
- TOML aniqligi — taxminni yo'q qiladi
- Sozlama uchun ishonchlilik qulaylikdan muhim
- TOML tekis sozlama, YAML chuqur tuzilma; ikkovida ham sxema tekshiruvi
Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.
Xulosa
Bu darsda odam yozadigan ikki sozlama formatini — YAML va TOML ni o'rgandik.
Eng muhim uch fikr:
YAML "qulay", lekin turni taxmin qiladi.
yes/on/true→True,NO→False(Norway problem),1.10→1.1,22:22→1342,2026-09-17→date. Yechim — tuzoqli qiymatlarni qo'shtirnoqqa olish. Va har doimsafe_load/safe_dump: oddiyyaml.load!!python/objectteglari orqalipicklekabi kod bajaradi. Chiqishdaallow_unicode=True, chekinish faqat bo'shliq bilan.TOML — qat'iy va aniq. Satr qo'shtirnoqda, faqat
true/false,nullyo'q, takroriy kalit xato, native sana va son.[jadval]ichma-ich lug'at,[[massiv]]lug'atlar ro'yxati.tomllib(3.11+ stdlib) faqat o'qiydi va faylni"rb"rejimda oladi; yozish uchuntomli_w. Qat'iyligi tufayli xatolar sozlama yozilishida, ishga tushganda emas, topiladi.Format nima bo'lishidan qat'i nazar — tekshirish shart. Sozlamani yuklash — birinchi qadam; ikkinchisi — sukut qiymatlar bilan ichma-ich birlashtirish va sxema bo'yicha (turlar, majburiylik, oraliq) tekshirish. TOML — tekis loyiha sozlamasi (
pyproject.toml), YAML — chuqur infratuzilma (Kubernetes, CI/CD), JSON — mashinalararo almashinuv; sirlar esa hech qachon sozlama faylida emas.
Keyingi darsda ma'lumotni saqlashning kuchli usulini — o'rnatilgan sqlite3 bazasini o'rganamiz: SQL asoslari, parametrli so'rovlar (SQL injection dan himoya), tranzaksiyalar va Python obyektlarini jadvalga bog'lash.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!