Mundarija (26)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Asosiy sintaksis
- 2.2. Naqsh turlari — to'liq ro'yxat
- 2.3. Nom bog'lash tuzog'i — batafsil
- 2.4. Ketma-ketlik naqshlari — batafsil
- 2.5. Lug'at va sinf naqshlari
- 2.6. Qachon match, qachon boshqa narsa
- 2.7. Tezlik
- 2.8. Versiya mosligi
- 2.9. Amaliy naqshlar
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Barcha naqsh turi
- Misol 2 — Nom bog'lash tuzog'i
- Misol 3 — Amaliy qo'llanishlar
- Misol 4 — Qachon match, qachon boshqa narsa
- 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
- 5-QISM YAKUNLANDI
- BOSQICH 1 — POYDEVOR YAKUNLANDI
- Keyingi qadam: BOSQICH 2 — TIL USTASI (77 dars)
5.12-dars: match / case (3.10+)
5-QISM — BOSHQARUV OQIMI · 12-dars · 5-qism va BOSQICH 1 ning yakuni
1. Kirish va motivatsiya
1-darsda aytgandik: Pythonda switch yo'q. 2021-yilda Python 3.10 buni o'zgartirdi — lekin kutilganidek emas.
match/case — oddiy switch emas. U — strukturaviy naqsh moslashtirish (structural pattern matching), Rust, Scala va Haskell'dagi kabi.
Oddiy switch shunday ko'rinardi:
match buyruq:
case "boshla":
boshla()
case "to'xtat":
toxtat()
case _:
print("Noma'lum buyruq")Lekin match ancha kuchliroq — u tuzilmani ochadi:
match javob:
case {"holat": "ok", "malumot": malumot}:
return malumot
case {"holat": "xato", "kod": int(kod)} if kod >= 500:
raise ServerXatosi(kod)
case {"holat": "xato", "xabar": str(xabar)}:
raise MijozXatosi(xabar)
case _:
raise ValueError("Noma'lum javob")Bitta konstruksiyada: shakl tekshiruvi, tur tekshiruvi, qiymat ochish va qo'shimcha shart.
Bu darsda:
match/casesintaksisi va barcha naqsh turi- Nima uchun bu
switchemas - Eng ko'p uchraydigan tuzoq — nom bog'lash
- Qachon
match, qachonif/elifyoki lug'at - Amaliy qo'llanishlar
2. Nazariya — chuqur tushuntirish
2.1. Asosiy sintaksis
match <ifoda>:
case <naqsh1>:
<blok1>
case <naqsh2>:
<blok2>
case _:
<sukut blok>def javob(kod: int) -> str:
match kod:
case 200:
return "OK"
case 404:
return "Topilmadi"
case 500:
return "Server xatosi"
case _:
return "Noma'lum"
print(javob(200)) # 'OK'
print(javob(999)) # "Noma'lum"Muhim jihatlar:
- Birinchi mos keladigan
casebajariladi breakkerak emas — C dagi kabi "fallthrough" yo'q_— joker (wildcard), har narsaga mos keladi- Hech biri mos kelmasa — hech narsa bajarilmaydi (xato yo'q)
match va case — "yumshoq kalit so'zlar":
match = 5 # ✅ o'zgaruvchi sifatida ishlatish mumkin
case = "test" # ✅
print(match, case) # 5 testPython ularni kontekstga qarab ajratadi. Bu — moslikni saqlash uchun.
2.2. Naqsh turlari — to'liq ro'yxat
1. Literal naqsh:
match x:
case 42: ... # son
case "matn": ... # satr
case True: ... # bool
case None: ... # None
case 3.14: ... # kasr None, True, False — is bilan solishtiriladi, qolganlari == bilan.
2. Nom bog'lash (capture) — ENG KATTA TUZOQ:
match x:
case y: # ❌ HAR NARSAGA mos keladi!
print(y) # va x ni y ga bog'laydiBu — switch emas! case y "agar x == y bo'lsa" emas, balki "x ni y ga bog'la" degani.
QIYMAT = 42
match 100:
case QIYMAT: # ❌ QIYMAT ga 100 bog'lanadi!
print("Mos keldi") # HAR DOIM bajariladi
print(QIYMAT) # 100 ← o'zgaruvchi qayta yozildi!Yechim — nuqta bilan yozish:
class Doimiylar:
QIYMAT = 42
match 100:
case Doimiylar.QIYMAT: # ✅ qiymat bilan solishtirish
print("Mos keldi") # bajarilmaydiYoki Enum bilan (8-qism):
from enum import Enum
class Holat(Enum):
FAOL = 1
NOFAOL = 2
match h:
case Holat.FAOL: ... # ✅ nuqta bor — qiymat solishtiruviQoida:
Naqshda oddiy nom — bog'lash. Nuqtali nom — qiymat solishtiruvi.
3. Joker (_):
match x:
case 1: ...
case _: ... # qolgan hamma holat_ — maxsus: u bog'lamaydi, faqat mos keladi.
4. VA naqsh (|) — bir necha variant:
match kod:
case 200 | 201 | 204:
return "Muvaffaqiyat"
case 400 | 401 | 403 | 404:
return "Mijoz xatosi"
case 500 | 502 | 503:
return "Server xatosi"5. Ketma-ketlik naqshi:
match nuqta:
case [0, 0]:
print("Markaz")
case [x, 0]:
print(f"X o'qida: {x}")
case [0, y]:
print(f"Y o'qida: {y}")
case [x, y]:
print(f"Nuqta: ({x}, {y})") Ketma-ketlik naqshi list va tuple ga mos keladi, lekin str ga YO'Q:
match [1, 2]:
case [a, b]: print("mos") # ✅
match (1, 2):
case [a, b]: print("mos") # ✅ tuple ham
match "ab":
case [a, b]: print("mos") # ❌ satr mos kelmaydiBu — ataylab: satr ham ketma-ketlik, lekin uni belgilarga ajratish deyarli hech qachon kerak emas.
6. Yulduzcha (*) — qolgan elementlar:
match royxat:
case []:
print("Bo'sh")
case [x]:
print(f"Bitta: {x}")
case [x, y]:
print(f"Ikkita: {x}, {y}")
case [birinchi, *qolgani]:
print(f"Birinchi: {birinchi}, qolgani: {qolgani}")7. Lug'at naqshi:
match malumot:
case {"turi": "doira", "radius": r}:
return 3.14159 * r ** 2
case {"turi": "to'rtburchak", "en": e, "bo'y": b}:
return e * bLug'at naqshi — QISMAN moslik:
match {"a": 1, "b": 2, "c": 3}:
case {"a": 1}: # ✅ mos keladi — qolgan kalitlar e'tiborsiz
print("mos")Bu — ketma-ketlikdan farqi: [1] faqat bir elementli ro'yxatga mos keladi.
Barcha kalitni tekshirish uchun ** ishlating:
match malumot:
case {"a": 1, **qolgani} if not qolgani: # ✅ faqat "a" bo'lsa
...8. Sinf naqshi:
from dataclasses import dataclass
@dataclass
class Nuqta:
x: int
y: int
match nuqta:
case Nuqta(x=0, y=0):
print("Markaz")
case Nuqta(x=0, y=y):
print(f"Y o'qida: {y}")
case Nuqta(x=x, y=y):
print(f"({x}, {y})")Pozitsion argumentlar — __match_args__ bilan:
@dataclass
class Nuqta:
x: int
y: int
# dataclass avtomatik __match_args__ = ("x", "y") yaratadi
match nuqta:
case Nuqta(0, 0): # ✅ pozitsion
print("Markaz")Tur tekshiruvi:
match qiymat:
case int():
print("Butun son")
case str():
print("Satr")
case list():
print("Ro'yxat")Tur + bog'lash:
match qiymat:
case int(x) if x > 0:
print(f"Musbat butun: {x}")
case str(s) if len(s) > 10:
print(f"Uzun satr: {s[:10]}...")9. Qo'riqchi shart (if):
match nuqta:
case [x, y] if x == y:
print("Diagonal")
case [x, y] if x > 0 and y > 0:
print("Birinchi chorak")
case [x, y]:
print("Boshqa")Qo'riqchi shart naqsh mos kelgandan keyin tekshiriladi.
10. as naqshi — bog'lash bilan:
match malumot:
case {"turi": "doira", "radius": r} as shakl:
print(f"Shakl: {shakl}, radius: {r}")
case [Nuqta(0, 0) as boshi, *qolgani]:
print(f"Boshi: {boshi}")2.3. Nom bog'lash tuzog'i — batafsil
Bu — match bilan bog'liq eng katta muammo.
# ❌ Kutilgan: "x 42 ga tengmi"
QIYMAT = 42
x = 100
match x:
case QIYMAT:
print("Teng!") # HAR DOIM bajariladi
print(QIYMAT) # 100 — o'zgaruvchi qayta yozildi!Nega? Naqshda oddiy nom — bu bog'lash naqshi. U har narsaga mos keladi va nomga qiymat bog'laydi.
Uch yechim:
# 1. Nuqtali nom (nuqta bo'lishi kerak)
class Doimiylar:
QIYMAT = 42
match x:
case Doimiylar.QIYMAT: ... # ✅
# 2. Enum (8-qism) — eng yaxshi
from enum import Enum
class Kod(Enum):
OK = 200
XATO = 500
match kod:
case Kod.OK: ... # ✅
# 3. Modul orqali
import konfig
match x:
case konfig.QIYMAT: ... # ✅
# 4. Qo'riqchi shart
match x:
case y if y == QIYMAT: ... # ✅ ishlaydi, lekin chirkinYana bir tuzoq — bir necha bog'lash:
match nuqta:
case [x, x]: # ❌ SyntaxError
print("Bir xil")Bir naqshda bir xil nom ikki marta ishlatib bo'lmaydi.
To'g'ri:
match nuqta:
case [a, b] if a == b: # ✅
print("Bir xil") | bilan bog'lash:
match x:
case [1, y] | [2, y]: # ✅ har ikkala tarmoqda y bor
print(y)
case [1, y] | [2]: # ❌ SyntaxError — y faqat bir tarmoqda
...| bilan birlashtirilgan naqshlar bir xil nomlarni bog'lashi kerak.
2.4. Ketma-ketlik naqshlari — batafsil
def tahlil(malumot):
match malumot:
case []:
return "bo'sh"
case [x]:
return f"bitta: {x}"
case [x, y]:
return f"ikkita: {x}, {y}"
case [x, y, *qolgani]:
return f"ko'p: {x}, {y} + yana {len(qolgani)} ta"
case _:
return "ketma-ketlik emas"
for m in [[], [1], [1, 2], [1, 2, 3, 4], "abc", 42]:
print(f" {m!r:<14} → {tahlil(m)}") [] → bo'sh
[1] → bitta: 1
[1, 2] → ikkita: 1, 2
[1, 2, 3, 4] → ko'p: 1, 2 + yana 2 ta
'abc' → ketma-ketlik emas
42 → ketma-ketlik emasSatr ketma-ketlik naqshiga mos kelmaydi — bu ataylab.
Ichma-ich naqshlar:
match malumot:
case [[a, b], [c, d]]:
print(f"2×2 matritsa: {a} {b} / {c} {d}")
case [{"ism": ism}, *qolgani]:
print(f"Birinchi: {ism}, yana {len(qolgani)} ta")Yulduzcha o'rtada ham:
match royxat:
case [birinchi, *orta, oxirgi]:
print(f"{birinchi} ... {oxirgi} ({len(orta)} ta o'rtada)") Bir naqshda bitta *:
case [*a, *b]: # ❌ SyntaxErrorSobit uzunlik:
case [_, _, _]: # aynan 3 element
case [_, _, *_]: # kamida 2 element2.5. Lug'at va sinf naqshlari
Lug'at — qisman moslik:
JAVOBLAR = [
{"holat": "ok", "malumot": [1, 2, 3]},
{"holat": "xato", "kod": 404, "xabar": "Topilmadi"},
{"holat": "xato", "kod": 500},
{"noma'lum": "format"},
]
for javob in JAVOBLAR:
match javob:
case {"holat": "ok", "malumot": malumot}:
print(f" ✅ {len(malumot)} ta element")
case {"holat": "xato", "kod": kod, "xabar": xabar}:
print(f" ❌ {kod}: {xabar}")
case {"holat": "xato", "kod": kod}:
print(f" ❌ {kod}: (xabar yo'q)")
case _:
print(f" ⚠️ Noma'lum format")Tartib muhim — aniqroq naqsh oldinda bo'lishi kerak.
Sinf naqshi:
from dataclasses import dataclass
@dataclass
class Doira:
radius: float
@dataclass
class Tortburchak:
en: float
boy: float
@dataclass
class Uchburchak:
a: float
b: float
c: float
def yuza(shakl) -> float:
match shakl:
case Doira(radius=r):
return 3.14159 * r ** 2
case Tortburchak(en=e, boy=b):
return e * b
case Uchburchak(a=a, b=b, c=c):
p = (a + b + c) / 2
return (p * (p-a) * (p-b) * (p-c)) ** 0.5
case _:
raise ValueError(f"Noma'lum shakl: {shakl}")Pozitsion argumentlar:
match shakl:
case Doira(r): # ✅ __match_args__ tufayli
return 3.14159 * r ** 2
case Tortburchak(e, b):
return e * b@dataclass avtomatik __match_args__ yaratadi. Oddiy sinf uchun qo'lda:
class Nuqta:
__match_args__ = ("x", "y")
def __init__(self, x, y):
self.x, self.y = x, yTur va qiymat birga:
match qiymat:
case int() | float() as son if son > 0:
print(f"Musbat son: {son}")
case str() as matn if matn.isdecimal():
print(f"Sonli satr: {matn}")2.6. Qachon match, qachon boshqa narsa
match yaxshi:
# 1. Tuzilmani ochish
match javob:
case {"holat": "ok", "malumot": m}: ...
# 2. Turli shakldagi ma'lumot
match hodisa:
case {"turi": "bosish", "x": x, "y": y}: ...
case {"turi": "tugma", "kod": kod}: ...
# 3. AST/token qayta ishlash
match tugun:
case BinaryOp(chap, "+", ong): ...
# 4. Rekursiv tuzilmalar
match daraxt:
case Barg(qiymat): ...
case Tugun(chap, ong): ... match ortiqcha:
# 1. Oddiy qiymat solishtiruvi → lug'at
match rang:
case "qizil": return "#FF0000"
case "yashil": return "#00FF00"
RANGLAR = {"qizil": "#FF0000", "yashil": "#00FF00"} # ✅ tezroq
return RANGLAR.get(rang, "#000000")
# 2. Diapazon tekshiruvi → if/elif
match ball:
case b if b >= 90: return "A"
case b if b >= 80: return "B"
if ball >= 90: return "A" # ✅ aniqroq
if ball >= 80: return "B"
# 3. Ikki holat → if/else
match bayroq:
case True: ...
case False: ...
if bayroq: ... # ✅
else: ...Qaror jadvali:
| Vaziyat | Yechim |
|---|---|
| Aniq qiymatlar (2-3 ta) | if/elif |
| Aniq qiymatlar (ko'p) | Lug'at |
| Diapazonlar | if/elif |
| Tuzilmani ochish | match |
| Turli shakldagi ma'lumot | match |
| Tur bo'yicha tarmoqlanish | match yoki isinstance |
| Rekursiv tuzilmalar | match |
2.7. Tezlik
import time
N = 1_000_000
# match
def match_bilan(x):
match x:
case 0: return "nol"
case 1: return "bir"
case 2: return "ikki"
case _: return "boshqa"
# if/elif
def if_bilan(x):
if x == 0: return "nol"
if x == 1: return "bir"
if x == 2: return "ikki"
return "boshqa"
# Lug'at
LUGAT = {0: "nol", 1: "bir", 2: "ikki"}
def lugat_bilan(x):
return LUGAT.get(x, "boshqa")Natija (taxminan):
lugat_bilan: 0.42 s ← eng tez (xesh jadval, O(1))
if_bilan: 0.58 s
match_bilan: 0.61 s match — switch emas, jadval sakrash (jump table) yaratmaydi. U ketma-ket tekshiradi, if/elif kabi.
Lekin murakkab naqshlarda match yutadi:
# match bilan — bitta o'tish
match javob:
case {"holat": "ok", "malumot": [birinchi, *qolgani]}: ...
# if bilan — bir necha tekshiruv
if (isinstance(javob, dict)
and javob.get("holat") == "ok"
and isinstance(javob.get("malumot"), list)
and len(javob["malumot"]) >= 1):
birinchi = javob["malumot"][0]
qolgani = javob["malumot"][1:]Xulosa: match — tezlik uchun emas, o'qish osonligi uchun.
2.8. Versiya mosligi
match/case — Python 3.10+.
import sys
if sys.version_info >= (3, 10):
# match ishlatish mumkin
... Eski versiyada SyntaxError — hatto kod bajarilmasa ham, chunki bu sintaksis darajasida.
Shuning uchun shartli import ishlamaydi:
if sys.version_info >= (3, 10):
match x: # ❌ 3.9 da SyntaxError (parse paytida)
case 1: ...Yechim — alohida modul:
# match_yordamchi.py (faqat 3.10+ da import qilinadi)
def ishla(x):
match x:
case ...: ...
# main.py
if sys.version_info >= (3, 10):
from match_yordamchi import ishla
else:
from oddiy_yordamchi import ishlapyproject.toml da (2.7-dars):
[project]
requires-python = ">=3.10"
[tool.ruff]
target-version = "py310"Amaliy maslahat: kutubxona yozayotgan bo'lsangiz va eski versiyalarni qo'llab-quvvatlash kerak bo'lsa — match ishlatmang. Ilova uchun — bemalol.
2.9. Amaliy naqshlar
1. HTTP javobini qayta ishlash:
def javobni_ishla(javob: dict):
match javob:
case {"status": 200, "data": data}:
return data
case {"status": 201, "id": id}:
return f"Yaratildi: {id}"
case {"status": 400 | 422, "errors": errors}:
raise ValidationError(errors)
case {"status": 401 | 403}:
raise AuthError()
case {"status": int(kod)} if kod >= 500:
raise ServerError(kod)
case _:
raise ValueError(f"Noma'lum javob: {javob}")2. Buyruq satri argumentlari:
import sys
match sys.argv[1:]:
case []:
yordam()
case ["--help" | "-h"]:
yordam()
case ["--version" | "-v"]:
print(VERSIYA)
case ["run", fayl]:
ishga_tushir(fayl)
case ["run", fayl, *bayroqlar]:
ishga_tushir(fayl, bayroqlar)
case [buyruq, *_]:
print(f"Noma'lum buyruq: {buyruq}")3. Hodisalarni qayta ishlash:
match hodisa:
case {"turi": "bosish", "tugma": "chap", "x": x, "y": y}:
chap_bosish(x, y)
case {"turi": "bosish", "tugma": "ong", "x": x, "y": y}:
ong_bosish(x, y)
case {"turi": "klaviatura", "kod": kod, "shift": True}:
katta_harf(kod)
case {"turi": "klaviatura", "kod": kod}:
oddiy_harf(kod)4. Rekursiv tuzilmalar:
@dataclass
class Barg:
qiymat: int
@dataclass
class Tugun:
chap: "Barg | Tugun"
ong: "Barg | Tugun"
def yigindi(daraxt) -> int:
match daraxt:
case Barg(qiymat=q):
return q
case Tugun(chap=c, ong=o):
return yigindi(c) + yigindi(o)
case _:
raise TypeError(f"Noma'lum tugun: {daraxt}")5. Ma'lumot tekshiruvi:
def tekshir(malumot) -> str:
match malumot:
case {"ism": str(ism), "yosh": int(yosh)} if 0 < yosh < 150:
return f"✅ {ism}, {yosh}"
case {"ism": str()}:
return "❌ Yosh noto'g'ri"
case {"yosh": int()}:
return "❌ Ism yo'q"
case dict():
return "❌ Majburiy maydonlar yetishmaydi"
case _:
return "❌ Lug'at kutilgan edi"3. Tez ma'lumotnoma
Sintaksis
match <ifoda>:
case <naqsh>: birinchi mos keladigan bajariladi
case <naqsh> if <shart>: qo'riqchi shart
case _: joker (sukut)Naqsh turlari
case 42: literal
case "matn" | "boshqa": yoki (|)
case x: ⚠️ BOG'LASH — har narsaga mos
case Modul.DOIMIY: qiymat solishtiruvi (nuqta kerak!)
case _: joker
case [a, b]: ketma-ketlik (list, tuple — str EMAS)
case [a, *qolgani]: yulduzcha
case {"kalit": q}: lug'at (QISMAN moslik)
case Sinf(x=1, y=y): sinf (nomli)
case Sinf(a, b): sinf (pozitsion, __match_args__)
case int() | float(): tur tekshiruvi
case [x, y] as juftlik: as bilan bog'lashENG KATTA TUZOQ
QIYMAT = 42
match 100:
case QIYMAT: ❌ QIYMAT ga 100 BOG'LANADI
... har doim bajariladi
case Doimiylar.QIYMAT: ✅ nuqta bilan
case Enum.QIYMAT: ✅ eng yaxshi
case y if y == QIYMAT: ✅ qo'riqchi shartFarqlar
Ketma-ketlik: [1] → AYNAN bir elementli
Lug'at: {"a": 1} → QISMAN (qolgan kalitlar e'tiborsiz)
Satr: ketma-ketlik naqshiga MOS KELMAYDIQachon match
✅ Tuzilmani ochish, turli shakldagi ma'lumot, rekursiv tuzilma
❌ Oddiy qiymat solishtiruvi → lug'at
❌ Diapazonlar → if/elif
❌ Ikki holat → if/elseVersiya
Python 3.10+ — eski versiyada SyntaxError (parse paytida)4. Batafsil misollar
Misol 1 — Barcha naqsh turi
"""match/case — to'liq ma'lumotnoma."""
import sys
from dataclasses import dataclass
from enum import Enum
if sys.version_info < (3, 10):
print("⚠️ match/case Python 3.10+ talab qiladi")
sys.exit(1)
print("=== 1. Literal naqshlar ===")
def literal(x):
match x:
case 42:
return "son 42"
case "salom":
return "salom satri"
case True:
return "True"
case None:
return "None"
case 3.14:
return "pi"
case _:
return f"boshqa: {x!r}"
for x in [42, "salom", True, None, 3.14, "boshqa", 0]:
print(f" {x!r:<10} → {literal(x)}")
print("\n ⚠️ True/False/None — `is` bilan, qolganlari `==` bilan")
print("\n\n=== 2. | (yoki) naqshi ===")
def http_turi(kod: int) -> str:
match kod:
case 200 | 201 | 204:
return "✅ Muvaffaqiyat"
case 301 | 302 | 307 | 308:
return "↪️ Yo'naltirish"
case 400 | 401 | 403 | 404 | 422:
return "❌ Mijoz xatosi"
case 500 | 502 | 503 | 504:
return "🔴 Server xatosi"
case _:
return "❓ Noma'lum"
for kod in [200, 301, 404, 500, 999]:
print(f" {kod} → {http_turi(kod)}")
print("\n\n=== 3. Ketma-ketlik naqshlari ===")
def tahlil_ketma_ketlik(x):
match x:
case []:
return "bo'sh"
case [a]:
return f"bitta: {a}"
case [a, b]:
return f"ikkita: {a}, {b}"
case [a, b, c]:
return f"uchta: {a}, {b}, {c}"
case [birinchi, *orta, oxirgi]:
return f"{birinchi} ... {oxirgi} ({len(orta)} o'rtada)"
case _:
return "ketma-ketlik emas"
for x in [[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4, 5],
(1, 2), "abc", 42, {"a": 1}]:
print(f" {x!r:<16} → {tahlil_ketma_ketlik(x)}")
print("\n ⚠️ Satr ketma-ketlik naqshiga MOS KELMAYDI (ataylab)")
print(" ✅ tuple ham mos keladi")
print("\n\n=== 4. Lug'at naqshlari ===")
def tahlil_lugat(x):
match x:
case {"turi": "doira", "radius": r}:
return f"Doira: r={r}, yuza={3.14159 * r**2:.2f}"
case {"turi": "to'rtburchak", "en": e, "bo'y": b}:
return f"To'rtburchak: {e}×{b}, yuza={e * b}"
case {"turi": turi}:
return f"Noma'lum shakl: {turi}"
case {}:
return "Bo'sh yoki 'turi' yo'q"
case _:
return "Lug'at emas"
NAMUNALAR = [
{"turi": "doira", "radius": 5},
{"turi": "doira", "radius": 5, "rang": "qizil"}, # ortiqcha kalit
{"turi": "to'rtburchak", "en": 3, "bo'y": 4},
{"turi": "uchburchak"},
{},
[1, 2],
]
for x in NAMUNALAR:
print(f" {str(x)[:38]:<40} → {tahlil_lugat(x)}")
print("\n ⭐ Lug'at naqshi — QISMAN moslik (ortiqcha kalitlar e'tiborsiz)")
print("\n\n=== 5. Sinf naqshlari ===")
@dataclass
class Nuqta:
x: float
y: float
@dataclass
class Doira:
markaz: Nuqta
radius: float
def tahlil_sinf(shakl):
match shakl:
case Nuqta(x=0, y=0):
return "Koordinata boshi"
case Nuqta(x=0, y=y):
return f"Y o'qida: y={y}"
case Nuqta(x=x, y=0):
return f"X o'qida: x={x}"
case Nuqta(x=x, y=y) if x == y:
return f"Diagonalda: ({x}, {y})"
case Nuqta(x, y): # pozitsion
return f"Nuqta: ({x}, {y})"
case Doira(markaz=Nuqta(0, 0), radius=r):
return f"Markazda joylashgan doira: r={r}"
case Doira(markaz=m, radius=r):
return f"Doira: markaz={m}, r={r}"
case _:
return "Noma'lum shakl"
for shakl in [
Nuqta(0, 0), Nuqta(0, 5), Nuqta(3, 0), Nuqta(2, 2), Nuqta(1, 7),
Doira(Nuqta(0, 0), 10), Doira(Nuqta(1, 1), 5), "boshqa",
]:
print(f" {str(shakl):<32} → {tahlil_sinf(shakl)}")
print("\n\n=== 6. Tur naqshlari ===")
def tur_tahlil(x):
match x:
case int(n) if n < 0:
return f"Manfiy butun: {n}"
case int(n):
return f"Musbat butun: {n}"
case float(f):
return f"Kasr: {f}"
case str(s) if s.isdecimal():
return f"Sonli satr: {s}"
case str(s):
return f"Satr ({len(s)} belgi)"
case list() | tuple() as ketma:
return f"Ketma-ketlik ({len(ketma)} element)"
case dict() as d:
return f"Lug'at ({len(d)} kalit)"
case None:
return "None"
case _:
return f"Boshqa: {type(x).__name__}"
for x in [-5, 42, 3.14, "123", "salom", [1, 2], (1, 2), {"a": 1}, None, set()]:
print(f" {x!r:<12} → {tur_tahlil(x)}")
print("\n\n=== 7. as naqshi ===")
def as_naqsh(x):
match x:
case {"turi": "user", "id": int(uid)} as malumot:
return f"Foydalanuvchi #{uid}, to'liq: {malumot}"
case [Nuqta(0, 0) as boshi, *qolgani]:
return f"Boshi {boshi}, yana {len(qolgani)} nuqta"
case _:
return "Mos kelmadi"
print(f" {as_naqsh({'turi': 'user', 'id': 42})}")
print(f" {as_naqsh([Nuqta(0, 0), Nuqta(1, 1), Nuqta(2, 2)])}")Natijaning muhim qismi:
=== 3. Ketma-ketlik naqshlari ===
[] → bo'sh
[1] → bitta: 1
[1, 2] → ikkita: 1, 2
[1, 2, 3] → uchta: 1, 2, 3
[1, 2, 3, 4, 5] → 1 ... 5 (3 o'rtada)
(1, 2) → ikkita: 1, 2
'abc' → ketma-ketlik emas
42 → ketma-ketlik emas
{'a': 1} → ketma-ketlik emas
=== 4. Lug'at naqshlari ===
{'turi': 'doira', 'radius': 5} → Doira: r=5, yuza=78.54
{'turi': 'doira', 'radius': 5, 'rang'... → Doira: r=5, yuza=78.54
⭐ Lug'at naqshi — QISMAN moslikNima ko'rsatdi: 2.2, 2.4, 2.5-bo'limlar.
Misol 2 — Nom bog'lash tuzog'i
"""match ning eng katta tuzog'i."""
from enum import Enum
print("=== 1. ❌ Muammo ===")
QIYMAT = 42
x = 100
print(f" QIYMAT = {QIYMAT}, x = {x}\n")
# ⚠️ Agar "case QIYMAT:" dan keyin yana naqsh bo'lsa, Python buni
# KOMPILYATSIYADA ushlaydi — butun fayl ishga tushmaydi:
KOD = """
match x:
case QIYMAT:
pass
case _:
pass
"""
try:
compile(KOD, "<misol>", "exec")
except SyntaxError as e:
print(f" Keyin case _ bo'lsa → ❌ SyntaxError: {e.msg}\n")
# ⚠️ Lekin u OXIRGI naqsh bo'lsa — hech qanday ogohlantirish yo'q:
match x:
case QIYMAT:
print(f" case QIYMAT: BAJARILDI (kutilmagan!)")
print(f"\n QIYMAT endi = {QIYMAT} ← ❌ QAYTA YOZILDI!")
print("""
Sabab: naqshda ODDIY NOM — bu BOG'LASH naqshi.
U har narsaga mos keladi va nomga qiymat bog'laydi.
`case QIYMAT:` = "x ni QIYMAT nomiga bog'la"
emas = "x QIYMAT ga tengmi"
""")
print("=== 2. ✅ Yechim 1: nuqtali nom ===")
class Doimiylar:
QIYMAT = 42
BOSHQA = 100
QIYMAT = 42 # qayta tiklash
for x in [42, 100, 7]:
match x:
case Doimiylar.QIYMAT:
natija = "QIYMAT (42) bilan mos"
case Doimiylar.BOSHQA:
natija = "BOSHQA (100) bilan mos"
case _:
natija = "mos kelmadi"
print(f" x={x:>4} → {natija}")
print("\n\n=== 3. ✅ Yechim 2: Enum (eng yaxshi) ===")
class Holat(Enum):
FAOL = "faol"
NOFAOL = "nofaol"
BLOKLANGAN = "bloklangan"
def holat_matni(h):
match h:
case Holat.FAOL:
return "✅ Faol"
case Holat.NOFAOL:
return "⏸️ Nofaol"
case Holat.BLOKLANGAN:
return "🔴 Bloklangan"
case _:
return "❓ Noma'lum"
for h in [Holat.FAOL, Holat.NOFAOL, Holat.BLOKLANGAN, "boshqa"]:
print(f" {str(h):<24} → {holat_matni(h)}")
print("\n ⭐ Enum — nuqta bor, shuning uchun qiymat solishtiruvi")
print("\n\n=== 4. ✅ Yechim 3: qo'riqchi shart ===")
QIYMAT = 42
for x in [42, 100]:
match x:
case y if y == QIYMAT:
natija = f"QIYMAT bilan mos"
case _:
natija = "mos kelmadi"
print(f" x={x:>4} → {natija}")
print("\n ⚠️ Ishlaydi, lekin chirkin — Enum yaxshiroq")
print("\n\n=== 5. ⚠️ Bir naqshda takroriy nom ===")
print("""
❌ SyntaxError:
match nuqta:
case [x, x]: # bir xil nom ikki marta
print("Bir xil")
✅ Qo'riqchi shart bilan:
match nuqta:
case [a, b] if a == b:
print("Bir xil")
""")
def bir_xilmi(nuqta):
match nuqta:
case [a, b] if a == b:
return "Bir xil"
case [a, b]:
return f"Farqli: {a} != {b}"
case _:
return "Juftlik emas"
for n in [[1, 1], [1, 2], [5]]:
print(f" {n!r:<10} → {bir_xilmi(n)}")
print("\n\n=== 6. ⚠️ | bilan bog'lash ===")
print("""
✅ Har ikkala tarmoqda bir xil nomlar:
case [1, y] | [2, y]:
print(y)
❌ SyntaxError — nomlar mos kelmaydi:
case [1, y] | [2]:
...
""")
def yoki_bilan(x):
match x:
case [1, y] | [2, y]:
return f"Birinchi 1 yoki 2, ikkinchi: {y}"
case [a, b]:
return f"Boshqa juftlik: {a}, {b}"
case _:
return "Juftlik emas"
for x in [[1, 5], [2, 7], [3, 9]]:
print(f" {x!r:<10} → {yoki_bilan(x)}")
print("\n\n=== 7. `_` — maxsus joker ===")
print("""
`_` — bog'lamaydi, faqat mos keladi:
case _: ✅ joker
case [_, _]: ✅ ikki elementli, qiymatlar kerak emas
case {"a": _}: ✅ "a" kaliti bor
case [x, _, y]: ✅ o'rtadagi kerak emas
""")
def joker(x):
match x:
case [_, _, _]:
return "aynan uch element"
case [_, _]:
return "aynan ikki element"
case [_]:
return "bitta element"
case _:
return "boshqa"
for x in [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]:
print(f" {x!r:<14} → {joker(x)}")Natijaning muhim qismi:
=== 1. ❌ Muammo ===
QIYMAT = 42, x = 100
case QIYMAT: BAJARILDI (kutilmagan!)
QIYMAT endi = 100 ← ❌ QAYTA YOZILDI!
=== 3. ✅ Yechim 2: Enum (eng yaxshi) ===
Holat.FAOL → ✅ Faol
Holat.NOFAOL → ⏸️ Nofaol
Holat.BLOKLANGAN → 🔴 Bloklangan
boshqa → ❓ Noma'lum
⭐ Enum — nuqta bor, shuning uchun qiymat solishtiruviNima ko'rsatdi: 2.3-bo'lim.
Misol 3 — Amaliy qo'llanishlar
"""match/case real vazifalarda."""
from dataclasses import dataclass
from enum import Enum
print("=== 1. HTTP javobini qayta ishlash ===")
class XatoTuri(Exception):
pass
def javobni_ishla(javob: dict):
match javob:
case {"status": 200, "data": data}:
return f"✅ Ma'lumot: {data}"
case {"status": 201, "id": id}:
return f"✅ Yaratildi: #{id}"
case {"status": 204}:
return "✅ Bajarildi (mazmun yo'q)"
case {"status": 400 | 422, "errors": errors}:
return f"❌ Tekshiruv xatosi: {errors}"
case {"status": 401}:
return "❌ Autentifikatsiya kerak"
case {"status": 403}:
return "❌ Ruxsat yo'q"
case {"status": 404, "resource": res}:
return f"❌ Topilmadi: {res}"
case {"status": int(kod), "message": msg} if kod >= 500:
return f"🔴 Server xatosi {kod}: {msg}"
case {"status": int(kod)} if kod >= 500:
return f"🔴 Server xatosi {kod}"
case {"status": int(kod)}:
return f"❓ Noma'lum status: {kod}"
case _:
return "❌ Noto'g'ri javob formati"
JAVOBLAR = [
{"status": 200, "data": [1, 2, 3]},
{"status": 201, "id": 42},
{"status": 204},
{"status": 400, "errors": {"ism": "majburiy"}},
{"status": 401},
{"status": 404, "resource": "/users/999"},
{"status": 500, "message": "Ichki xato"},
{"status": 503},
{"status": 999},
{"noma'lum": "format"},
]
for javob in JAVOBLAR:
print(f" {str(javob)[:42]:<44} → {javobni_ishla(javob)}")
print("\n\n=== 2. Buyruq satri argumentlari ===")
def buyruqni_ishla(argv: list[str]) -> str:
match argv:
case []:
return "Yordam ko'rsatiladi"
case ["--help" | "-h"]:
return "Yordam"
case ["--version" | "-v"]:
return "Versiya 1.0.0"
case ["run", fayl]:
return f"Ishga tushirish: {fayl}"
case ["run", fayl, *bayroqlar]:
return f"Ishga tushirish: {fayl}, bayroqlar: {bayroqlar}"
case ["test", *_] if "--verbose" in argv:
return "Test (batafsil rejim)"
case ["test", *fayllar]:
return f"Test: {fayllar or 'barcha'}"
case [buyruq, *_]:
return f"❌ Noma'lum buyruq: {buyruq}"
ARGUMENTLAR = [
[],
["--help"],
["-v"],
["run", "main.py"],
["run", "main.py", "--debug", "--port=8000"],
["test"],
["test", "test_a.py", "test_b.py"],
["test", "--verbose"],
["nomalum"],
]
for argv in ARGUMENTLAR:
print(f" {str(argv)[:40]:<42} → {buyruqni_ishla(argv)}")
print("\n\n=== 3. Hodisalarni qayta ishlash ===")
def hodisani_ishla(hodisa: dict) -> str:
match hodisa:
case {"turi": "bosish", "tugma": "chap", "x": x, "y": y}:
return f"👆 Chap bosish: ({x}, {y})"
case {"turi": "bosish", "tugma": "ong", "x": x, "y": y}:
return f"👉 O'ng bosish: ({x}, {y})"
case {"turi": "bosish", "tugma": tugma}:
return f"❓ Noma'lum tugma: {tugma}"
case {"turi": "klaviatura", "kod": kod, "shift": True}:
return f"⌨️ Shift + {kod}"
case {"turi": "klaviatura", "kod": kod, "ctrl": True}:
return f"⌨️ Ctrl + {kod}"
case {"turi": "klaviatura", "kod": kod}:
return f"⌨️ {kod}"
case {"turi": "aylantirish", "yonalish": "yuqori", "miqdor": m}:
return f"⬆️ Yuqoriga: {m}"
case {"turi": "aylantirish", "yonalish": "past", "miqdor": m}:
return f"⬇️ Pastga: {m}"
case {"turi": turi}:
return f"❓ Noma'lum hodisa: {turi}"
case _:
return "❌ Noto'g'ri format"
HODISALAR = [
{"turi": "bosish", "tugma": "chap", "x": 100, "y": 200},
{"turi": "bosish", "tugma": "ong", "x": 50, "y": 75},
{"turi": "klaviatura", "kod": "A", "shift": True},
{"turi": "klaviatura", "kod": "C", "ctrl": True},
{"turi": "klaviatura", "kod": "x"},
{"turi": "aylantirish", "yonalish": "yuqori", "miqdor": 3},
{"turi": "nomalum"},
]
for h in HODISALAR:
print(f" {str(h)[:48]:<50} → {hodisani_ishla(h)}")
print("\n\n=== 4. Rekursiv tuzilma — ifoda daraxti ===")
@dataclass
class Son:
qiymat: float
@dataclass
class Amal:
chap: "Son | Amal"
operator: str
ong: "Son | Amal"
def hisobla(ifoda) -> float:
match ifoda:
case Son(qiymat=q):
return q
case Amal(chap=c, operator="+", ong=o):
return hisobla(c) + hisobla(o)
case Amal(chap=c, operator="-", ong=o):
return hisobla(c) - hisobla(o)
case Amal(chap=c, operator="*", ong=o):
return hisobla(c) * hisobla(o)
case Amal(chap=c, operator="/", ong=o):
bolvchi = hisobla(o)
if bolvchi == 0:
raise ZeroDivisionError("Nolga bo'lish")
return hisobla(c) / bolvchi
case _:
raise ValueError(f"Noma'lum ifoda: {ifoda}")
def korsat(ifoda) -> str:
match ifoda:
case Son(qiymat=q):
return str(q)
case Amal(chap=c, operator=op, ong=o):
return f"({korsat(c)} {op} {korsat(o)})"
case _:
return "?"
# (2 + 3) * (10 - 4)
IFODA = Amal(
Amal(Son(2), "+", Son(3)),
"*",
Amal(Son(10), "-", Son(4)),
)
print(f" Ifoda: {korsat(IFODA)}")
print(f" Natija: {hisobla(IFODA)}")
# Ichma-ich
IFODA2 = Amal(
Amal(Son(100), "/", Son(4)),
"+",
Amal(Amal(Son(2), "*", Son(3)), "-", Son(1)),
)
print(f"\n Ifoda: {korsat(IFODA2)}")
print(f" Natija: {hisobla(IFODA2)}")
print("\n\n=== 5. Ma'lumot tekshiruvi ===")
def tekshir(malumot) -> str:
match malumot:
case {"ism": str(ism), "yosh": int(yosh), "email": str(email)} \
if 0 < yosh < 150 and "@" in email:
return f"✅ {ism}, {yosh} yosh, {email}"
case {"ism": str(), "yosh": int(yosh)} if not 0 < yosh < 150:
return f"❌ Yosh noto'g'ri: {yosh}"
case {"ism": str(), "yosh": int(), "email": str(email)}:
return f"❌ Email noto'g'ri: {email}"
case {"ism": str(), "yosh": _}:
return "❌ Yosh butun son bo'lishi kerak"
case {"ism": _}:
return "❌ Ism satr bo'lishi kerak"
case dict():
return "❌ 'ism' maydoni yetishmaydi"
case _:
return "❌ Lug'at kutilgan edi"
MALUMOTLAR = [
{"ism": "Ali", "yosh": 25, "email": "ali@example.com"},
{"ism": "Vali", "yosh": 200, "email": "vali@example.com"},
{"ism": "Guli", "yosh": 30, "email": "notogri"},
{"ism": "Sardor", "yosh": "25"},
{"ism": 42, "yosh": 30},
{"yosh": 25},
[1, 2, 3],
]
for m in MALUMOTLAR:
print(f" {str(m)[:44]:<46} → {tekshir(m)}")Natijaning muhim qismi:
=== 2. Buyruq satri argumentlari ===
[] → Yordam ko'rsatiladi
['--help'] → Yordam
['-v'] → Versiya 1.0.0
['run', 'main.py'] → Ishga tushirish: main.py
['run', 'main.py', '--debug', '--port=80 → Ishga tushirish: main.py, bayroqlar: ['--debug', '--port=8000']
['test'] → Test: barcha
['test', 'test_a.py', 'test_b.py'] → Test: ['test_a.py', 'test_b.py']
['test', '--verbose'] → Test (batafsil rejim)
=== 4. Rekursiv tuzilma — ifoda daraxti ===
Ifoda: ((2 + 3) * (10 - 4))
Natija: 30
Ifoda: ((100 / 4) + ((2 * 3) - 1))
Natija: 30.0Nima ko'rsatdi: 2.9-bo'lim.
Misol 4 — Qachon match, qachon boshqa narsa
"""match/case ni to'g'ri tanlash."""
import time
from enum import Enum
print("=== 1. ❌ match ORTIQCHA — oddiy qiymat ===")
def rang_match(rang: str) -> str:
match rang:
case "qizil":
return "#FF0000"
case "yashil":
return "#00FF00"
case "ko'k":
return "#0000FF"
case _:
return "#000000"
RANGLAR = {"qizil": "#FF0000", "yashil": "#00FF00", "ko'k": "#0000FF"}
def rang_lugat(rang: str) -> str:
return RANGLAR.get(rang, "#000000")
for r in ["qizil", "yashil", "binafsha"]:
m, l = rang_match(r), rang_lugat(r)
assert m == l
print(f" {r:<12} match={m} lugat={l}")
print("\n ✅ Lug'at — tezroq, ma'lumot koddan ajratilgan")
print("\n\n=== 2. ❌ match ORTIQCHA — diapazonlar ===")
def baho_match(ball: int) -> str:
match ball:
case b if b >= 90:
return "A"
case b if b >= 80:
return "B"
case b if b >= 70:
return "C"
case _:
return "D"
def baho_if(ball: int) -> str:
if ball >= 90:
return "A"
if ball >= 80:
return "B"
if ball >= 70:
return "C"
return "D"
for b in [95, 85, 75, 65]:
m, i = baho_match(b), baho_if(b)
assert m == i
print(f" {b:>4} match={m} if={i}")
print("\n ✅ if/elif — aniqroq, `case b if` chirkin")
print("\n\n=== 3. ✅ match KERAK — tuzilmani ochish ===")
print("""
match bilan — bitta konstruksiya:
match javob:
case {"holat": "ok", "malumot": [birinchi, *qolgani]}:
...
if bilan — bir necha tekshiruv:
if (isinstance(javob, dict)
and javob.get("holat") == "ok"
and isinstance(javob.get("malumot"), list)
and len(javob["malumot"]) >= 1):
birinchi = javob["malumot"][0]
qolgani = javob["malumot"][1:]
""")
def ishla_match(javob):
match javob:
case {"holat": "ok", "malumot": [birinchi, *qolgani]}:
return f"✅ Birinchi: {birinchi}, yana {len(qolgani)} ta"
case {"holat": "ok", "malumot": []}:
return "✅ Bo'sh"
case {"holat": "xato", "xabar": xabar}:
return f"❌ {xabar}"
case _:
return "❓ Noma'lum"
def ishla_if(javob):
if not isinstance(javob, dict):
return "❓ Noma'lum"
holat = javob.get("holat")
if holat == "ok":
malumot = javob.get("malumot")
if isinstance(malumot, list):
if not malumot:
return "✅ Bo'sh"
return f"✅ Birinchi: {malumot[0]}, yana {len(malumot) - 1} ta"
elif holat == "xato":
xabar = javob.get("xabar")
if xabar is not None:
return f"❌ {xabar}"
return "❓ Noma'lum"
JAVOBLAR = [
{"holat": "ok", "malumot": [1, 2, 3]},
{"holat": "ok", "malumot": []},
{"holat": "xato", "xabar": "Ulanish yo'q"},
{"noma'lum": True},
]
for j in JAVOBLAR:
m, i = ishla_match(j), ishla_if(j)
assert m == i, f"{m} != {i}"
print(f" {str(j)[:36]:<38} → {m}")
print("\n ✅ match — ancha o'qiladigan")
print("\n\n=== 4. Tezlik ===")
N = 500_000
def match_bilan(x):
match x:
case 0: return "nol"
case 1: return "bir"
case 2: return "ikki"
case _: return "boshqa"
def if_bilan(x):
if x == 0: return "nol"
if x == 1: return "bir"
if x == 2: return "ikki"
return "boshqa"
LUGAT = {0: "nol", 1: "bir", 2: "ikki"}
def lugat_bilan(x):
return LUGAT.get(x, "boshqa")
natijalar = []
for nom, f in [("match", match_bilan), ("if/elif", if_bilan),
("lug'at", lugat_bilan)]:
boshlandi = time.perf_counter()
for i in range(N):
f(i % 4)
natijalar.append((nom, time.perf_counter() - boshlandi))
eng_tez = min(v for _, v in natijalar)
print(f" {N:,} chaqiruv:\n")
print(f" {'Usul':<12} {'Vaqt':>9} {'Nisbat':>8}")
print(" " + "─" * 32)
for nom, vaqt in sorted(natijalar, key=lambda x: x[1]):
print(f" {nom:<12} {vaqt * 1000:>6.1f} ms {vaqt / eng_tez:>7.2f}x")
print("""
⚠️ match — `switch` EMAS, jadval sakrash yaratmaydi.
U ketma-ket tekshiradi, `if`/`elif` kabi.
⭐ match — tezlik uchun emas, O'QISH OSONLIGI uchun.
""")
print("=== 5. Qaror jadvali ===")
print(f"""
{'Vaziyat':<36} {'Yechim'}
{'─' * 62}
{'Aniq qiymatlar (2-3 ta)':<36} if/elif
{'Aniq qiymatlar (koʻp)':<36} ⭐ Lug'at
{'Diapazonlar':<36} if/elif
{'Ikki holat':<36} if/else
{'Tuzilmani ochish':<36} ⭐ match
{'Turli shakldagi maʻlumot':<36} ⭐ match
{'Tur boʻyicha tarmoqlanish':<36} match yoki isinstance
{'Rekursiv tuzilmalar':<36} ⭐ match
{'AST/token qayta ishlash':<36} ⭐ match
""")
print("=== 6. Versiya mosligi ===")
import sys
print(f" Joriy Python: {sys.version_info.major}.{sys.version_info.minor}")
print(f" match/case: 3.10+ da mavjud")
print("""
⚠️ Eski versiyada SyntaxError — PARSE paytida!
Shuning uchun shartli import ishlamaydi:
if sys.version_info >= (3, 10):
match x: # ❌ 3.9 da SyntaxError
case 1: ...
✅ Yechim — alohida modul:
# match_yordamchi.py (faqat 3.10+ da import)
# main.py:
if sys.version_info >= (3, 10):
from match_yordamchi import ishla
else:
from oddiy_yordamchi import ishla
✅ pyproject.toml:
requires-python = ">=3.10"
[tool.ruff] target-version = "py310"
""")Natijaning muhim qismi:
=== 4. Tezlik ===
500,000 chaqiruv:
Usul Vaqt Nisbat
────────────────────────────────
lug'at 42.1 ms 1.00x
if/elif 58.3 ms 1.38x
match 61.7 ms 1.47x
⚠️ match — `switch` EMAS, jadval sakrash yaratmaydi.
⭐ match — tezlik uchun emas, O'QISH OSONLIGI uchun.Nima ko'rsatdi: 2.6, 2.7, 2.8-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
"match — bu switch" |
Naqsh moslashtirish — ancha kuchliroq |
"case QIYMAT: qiymat bilan solishtiradi" |
Bog'laydi! Nuqtali nom yoki Enum kerak |
"match tezroq" |
if/elif bilan bir xil. Lug'at tezroq |
"break kerak" |
Yo'q — fallthrough yo'q |
| "Satr ketma-ketlik naqshiga mos keladi" | Ataylab yo'q |
| "Lug'at naqshi to'liq moslikni talab qiladi" | Qisman — ortiqcha kalitlar e'tiborsiz |
| "Hech biri mos kelmasa xato" | Hech narsa bajarilmaydi |
"match har doim yaxshi" |
Oddiy qiymatlar uchun lug'at yaxshiroq |
6. Keng tarqalgan xatolar va yechimlari
1. Nom bog'lash tuzog'i
QIYMAT = 42
match x:
case QIYMAT: # ❌ bog'laydi
...
case Doimiylar.QIYMAT: # ✅
case Holat.FAOL: # ✅ Enum
case y if y == QIYMAT: # ✅2. Takroriy nom
case [x, x]: # ❌ SyntaxError
case [a, b] if a == b: # ✅3. | bilan nomlar mos kelmasligi
case [1, y] | [2]: # ❌ SyntaxError
case [1, y] | [2, y]: # ✅4. Satr ketma-ketlik deb kutish
match "ab":
case [a, b]: ... # ❌ mos kelmaydi
case str(s): ... # ✅5. Lug'at to'liq moslik deb o'ylash
match {"a": 1, "b": 2}:
case {"a": 1}: ... # ✅ mos keladi (qisman)
case {"a": 1, **qolgani} if not qolgani: ... # ✅ faqat "a"6. Tartib noto'g'ri
match javob:
case {"holat": h}: ... # ❌ har doim mos keladi
case {"holat": "ok", "data": d}: ... # hech qachon yetib kelmaydi
case {"holat": "ok", "data": d}: ... # ✅ aniqroq oldinda
case {"holat": h}: ...7. Eski Python versiyasi
# Python 3.9 da SyntaxError — parse paytida
requires-python = ">=3.10" # ✅ pyproject.toml8. Oddiy holatda match
match x: # ⚠️ ortiqcha
case True: ...
case False: ...
if x: ... # ✅
else: ...7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 5.1-dars (o'tilgan):
if/elif, lug'at bilan tarmoqlanish - 6-qism: ro'yxat, lug'at — naqsh manbalari
- 8-qism:
Enum,dataclass,__match_args__ - 9-qism: istisnolarni turlar bo'yicha ajratish
- 13-qism: tur ishoralari bilan birga
- 10-qism:
__match_args__protokoli - 16-qism: JSON/API javoblarini qayta ishlash
- 12-qism: parser, AST, token qayta ishlash
8. Eng yaxshi amaliyotlar
Doimiylar uchun
Enumishlating. Oddiy nom naqshda bog'laydi, qiymat bilan solishtirmaydi.Aniqroq naqshni oldinga qo'ying. Umumiy naqsh keyingilarini soya qiladi.
Oddiy qiymatlar uchun lug'at.
match— tuzilmani ochish uchun.case _:ni qo'shing. Aks holda mos kelmaganda jimgina o'tib ketadi.Qo'riqchi shartni ishlating.
case [x, y] if x == y— takroriy nom o'rniga.Satr uchun
str()naqshi. Ketma-ketlik naqshiga mos kelmaydi.requires-python = ">=3.10"yozing. Eski versiyadaSyntaxError.Rekursiv tuzilmalarda ishlating. AST, daraxtlar, ichma-ich JSON —
matchning eng kuchli joyi.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
QIYMAT = 5
# a
match 10:
case QIYMAT: print("a")
case _: print("b")
print(QIYMAT)
# b
match [1, 2, 3]:
case [a, b]: print("ikki")
case [a, b, c]: print("uch")
case [a, *q]: print("ko'p")
# c
match {"a": 1, "b": 2}:
case {"a": 1}: print("mos")
case _: print("mos emas")
# d
match "ab":
case [x, y]: print("ketma-ketlik")
case str(): print("satr")Javoblar
a. a va 10 — QIYMAT ga 10 bog'landi!
b. uch — aniq uch elementli
c. mos — lug'at qisman moslik
d. satr — satr ketma-ketlik naqshiga mos kelmaydi
Vazifa 2: Xatolarni tuzatish
1. MAX = 100
match x:
case MAX: print("maksimal")
2. match nuqta:
case [x, x]: print("bir xil")
3. match javob:
case {"holat": h}: ...
case {"holat": "ok", "data": d}: ...
4. match x:
case [1, y] | [2]: print(y)Javoblar
1. class C: MAX = 100
match x:
case C.MAX: print("maksimal")
2. match nuqta:
case [a, b] if a == b: print("bir xil")
3. match javob:
case {"holat": "ok", "data": d}: ... # aniqroq oldinda
case {"holat": h}: ...
4. match x:
case [1, y] | [2, y]: print(y)Vazifa 3: Shakl kalkulyatori
match bilan yozing:
@dataclass
class Doira: radius: float
@dataclass
class Tortburchak: en: float; boy: float
@dataclass
class Uchburchak: a: float; b: float; c: floatFunksiyalar: yuza(shakl), perimetr(shakl), tavsif(shakl).
Qo'shing: Kvadrat (Tortburchak bo'lib en == boy).
Vazifa 4: JSON tahlilchisi
Turli shakldagi JSON javoblarni qayta ishlaydigan funksiya yozing:
{"type": "user", "id": 1, "name": "Ali"}
{"type": "list", "items": [...], "total": 100}
{"type": "error", "code": 404, "message": "..."}
{"type": "paginated", "items": [...], "page": 1, "next": "..."}Vazifa 5: Kalkulyator
match bilan oddiy kalkulyator yozing:
hisobla(["2", "+", "3"]) # 5
hisobla(["10", "/", "0"]) # ZeroDivisionError
hisobla(["sqrt", "16"]) # 4.0
hisobla(["max", "1", "5", "3"]) # 5Vazifa 6: Buyruq satri
3-misoldagi buyruqni_ishla ni kengaytiring:
--output FAYLbayrog'i-o FAYLqisqa shakli- Bir necha bayroq
--dan keyin — pozitsion argumentlar
Vazifa 7: O'ylash
Nega case QIYMAT: qiymat bilan solishtirmaydi?
Javob
Chunki match — naqsh moslashtirish, switch emas.
Naqsh moslashtirishning asosiy g'oyasi — tuzilmani ochish:
case Nuqta(x, y): # x va y ni BOG'LAYDI
case [birinchi, *qolgani]: # bog'laydi
case {"ism": ism}: # bog'laydiBu tillarda (Haskell, Rust, Scala) oddiy nom har doim bog'lash. Bu — izchil qoida.
Agar case QIYMAT: qiymat solishtiruvi bo'lganida:
case Nuqta(x, y): # x, y — qiymat solishtiruvi?
# yoki bog'lash?Qoida noaniq bo'lardi: qaysi nom bog'laydi, qaysi biri solishtiradi?
Yechim — sintaktik farq:
Oddiy nom → BOG'LASH (x, y, natija)
Nuqtali nom → SOLISHTIRISH (Modul.QIYMAT, Enum.A)
Literal → SOLISHTIRISH (42, "matn", None)Bu — aniq va izchil.
PEP 634 mualliflari buni muhokama qilishgan va nuqtali nom talabini ataylab qo'yishgan. Muqobil variantlar (masalan, case ==QIYMAT:) rad etilgan — chunki ular yangi sintaksis talab qilardi.
Amaliy xulosa: doimiylarni Enum da saqlang. U:
- Nuqtali nom beradi (
Holat.FAOL) - Tur xavfsizligini beradi
- IDE avtomatik to'ldirishi ishlaydi
- Xato yozuvda
AttributeErrorberadi
Nimani mustahkamlaydi: 2.2, 2.3, 2.5, 2.6-bo'limlar.
Xulosa
Bu darsda match/case ni o'rgandik.
Eng muhim uch fikr:
match—switchemas, naqsh moslashtirish. U tuzilmani ochadi, turni tekshiradi va qiymatlarni bog'laydi — bularning hammasi bitta konstruksiyada.case QIYMAT:— bu bog'lash, solishtirish emas. Bu — eng katta tuzoq. Doimiylar uchunEnumyoki nuqtali nom ishlating.match— tezlik uchun emas, o'qish osonligi uchun. Oddiy qiymat solishtiruvi uchun lug'at tezroq.match— turli shakldagi ma'lumot, rekursiv tuzilmalar va tuzilmani ochish uchun.
5-QISM YAKUNLANDI
O'n ikki darsni tugatdingiz:
| Dars | Nima o'rgandingiz |
|---|---|
| 5.1 | if/elif/else, shartlar tartibi, switch o'rniga lug'at |
| 5.2 | Qo'riqchi shart, murakkablik, refaktoring |
| 5.3 | and/or/not, De Morgan, any/all |
| 5.4 | Uchlik operator, prioritet, muqobillar |
| 5.5 | while, cheksiz sikl, while True + break |
| 5.6 | for, iteratsiya protokoli, ochish |
| 5.7 | range — ro'yxat emas, O(1) in |
| 5.8 | enumerate — range(len()) o'rniga |
| 5.9 | zip, transpozitsiya, strict=True |
| 5.10 | break, continue, sikl else |
| 5.11 | Ichma-ich sikllar, O(n²) → O(n) |
| 5.12 | match/case — naqsh moslashtirish |
BOSQICH 1 — POYDEVOR YAKUNLANDI
55 dars, 5 qism, ~24 000 qator.
| Qism | Darslar | Nima o'rgandingiz |
|---|---|---|
| 1. Kompyuter va dasturlash | 8 | Kompyuter qanday ishlaydi, Python nima va nega |
| 2. Muhit va vositalar | 9 | O'rnatish, terminal, VS Code, xato o'qish |
| 3. Asoslar | 14 | O'zgaruvchi, turlar, operatorlar, PEP 8 |
| 4. Satrlar chuqur | 12 | Metodlar, Unicode, kodlash, formatlash |
| 5. Boshqaruv oqimi | 12 | Shartlar, sikllar, match/case |
Endi siz:
- Python o'rnatilgan, professional sozlangan ish maydoni bor
- Xato xabarlarini o'qiy olasiz
- Barcha asosiy tur va operatorni bilasiz
- Matn bilan professional ishlay olasiz
- Mantiq va sikllar bilan istalgan algoritmni ifodalay olasiz
- Kodni PEP 8 ga mos va o'qiladigan yoza olasiz
Bu — poydevor. Undan keyingi hamma narsa shu ustiga quriladi.
Keyingi qadam: BOSQICH 2 — TIL USTASI (77 dars)
| Qism | Darslar | Mavzu |
|---|---|---|
| 6. Ma'lumot tuzilmalari | 18 | list, tuple, set, dict, generatorlar |
| 7. Funksiyalar | 14 | *args, LEGB, lambda, rekursiya |
| 8. OOP | 20 | Sinflar, meros, dunder metodlar, dataclass |
| 9. Xatolar va istisnolar | 8 | try/except, raise, o'z istisnolaringiz |
| 10. Ilg'or til imkoniyatlari | 17 | Iteratorlar, generatorlar, dekoratorlar, context manager, deskriptorlar |
6-qismdan boshlab siz ma'lumotni tashkil qilishni o'rganasiz — bu dasturchilikning yuragi.
Tabriklaymiz — eng qiyin qism ortda!
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!