Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Asosiy sintaksis
- 2.2. Yalang'och except:
- 2.3. Tur tanlash
- 2.4. as e — istisno obyekti
- 2.5. EAFP vs LBYL
- 2.6. Ichma-ich va qayta ko'tarish
- 2.7. Antipatternlar
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Mexanizm va tartib
- Misol 2 — EAFP vs LBYL
- Misol 3 — Qayta ko'tarish va ichma-ich
- Misol 4 — Amaliy: ishonchli ma'lumot yuklovchi
- 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
9.2-dars: try / except
9-QISM — XATOLAR VA ISTISNOLAR · 2-dars
1. Kirish va motivatsiya
Bu kod "xavfsiz" ko'rinadi:
try:
natija = hisobla(malumot)
except: # ⚠️
natija = NoneAslida u falokat:
try:
natija = hisobla(malumot)
except:
natija = None-
Ctrl+Cishlamaydi (KeyboardInterruptushlanadi) -
SystemExitto'siladi — dastur to'xtamaydi -
MemoryErroryashiriladi - Sizning typoingiz (
NameError) ham jimgina yutiladi - Xato sababi butunlay yo'qoladi
To'g'ri variant:
try:
natija = hisobla(malumot)
except (ValueError, KeyError) as e: # ⭐ ANIQ turlar
logging.warning("Hisoblab bo'lmadi: %s", e)
natija = NoneBu darsda:
-
try/exceptmexanizmi va bajarilish tartibi - Yalang'och
except:— nega taqiqlangan - Qaysi turni ushlash: aniqlikdan umumiylikka
as eva istisno obyekti- EAFP vs LBYL — Pythoncha uslub
- Ichma-ich
tryva qayta ko'tarish
2. Nazariya — chuqur tushuntirish
2.1. Asosiy sintaksis
try:
xavfli_amal() # ⭐ himoyalangan blok
except ValueError as e: # ⭐ tur + obyekt
ishlov(e)Bajarilish tartibi:
1. try bloki boshlanadi
2. Istisno bo'lmasa → except o'tkazib yuboriladi
3. Istisno bo'lsa:
a. try ning QOLGAN qismi BAJARILMAYDI
b. except turlari TARTIB BILAN tekshiriladi
c. Birinchi mos keladigan bajariladi
d. Hech biri mos kelmasa → yuqoriga uzatiladitry:
print("1")
1 / 0
print("2") # ⚠️ BAJARILMAYDI
except ZeroDivisionError:
print("3")
print("4")
# → 1, 3, 42.2. Yalang'och except:
try:
...
except: # ❌ HECH QACHON
... except: — except BaseException: bilan bir xil.
Ierarxiya:
BaseException ⚠️ except: shuni ushlaydi
├── SystemExit sys.exit()
├── KeyboardInterrupt Ctrl+C
├── GeneratorExit generator yopilishi
└── Exception ⭐ ODATIY xatolar
├── ValueError
├── TypeError
└── ... (barcha qolgani)Nima buziladi:
while True:
try:
ish()
except: # ⚠️ Ctrl+C ishlamaydi
continue # cheksiz tsikl!try:
sys.exit(1) # ⚠️ dastur to'xtamaydi
except:
print("nima bo'ldi?")try:
natija = hisoblaa(x) # ⚠️ typo: NameError
except:
natija = 0 # ⚠️ jimgina yashirildiTo'g'ri variantlar:
except Exception as e: # ⚠️ hali ham keng, lekin xavfsizroq
except (ValueError, KeyError) as e: # ✅ aniq
except ValueError as e: # ✅ eng aniq Qoida: except Exception: — faqat eng yuqori darajada (main(), veb ishlovchi), va doim jurnalga yozing.
2.3. Tur tanlash
Aniqlikdan umumiylikka:
try:
m = json.loads(matn)
q = m["kalit"]
n = int(q)
except json.JSONDecodeError: # ⭐ eng aniq
...
except KeyError:
...
except ValueError: # ⚠️ JSONDecodeError ham ValueError!
...Tartib muhim — birinchi mos keladigani ishlaydi:
except ValueError: ... # ⚠️ birinchi
except json.JSONDecodeError: ... # ❌ HECH QACHON ishlamaydi JSONDecodeError — ValueError avlodi, shuning uchun avval yozilishi kerak.
Bir nechta tur:
except (ValueError, TypeError) as e: # ⭐ tuple
except (ValueError, TypeError, KeyError):Guruh ushlash:
except LookupError: # KeyError + IndexError
except ArithmeticError: # ZeroDivisionError, OverflowError
except OSError: # barcha fayl/tarmoq2.4. as e — istisno obyekti
except ValueError as e:
print(type(e)) # <class 'ValueError'>
print(str(e)) # xabar
print(e.args) # (xabar,) — tuple
print(repr(e)) # ValueError('xabar')
print(e.__traceback__) # traceback obyekti e blok tugagach o'chiriladi:
try:
1 / 0
except ZeroDivisionError as e:
pass
print(e) # ❌ NameError Python 3 da except ... as e: blok oxirida del e qiladi — aylanma havolani oldini olish uchun.
Saqlash kerak bo'lsa:
xato = None
try:
...
except ValueError as e:
xato = e # ⭐ boshqa nomgaMaxsus atributlar:
except OSError as e:
e.errno # xato raqami
e.strerror # tizim xabari
e.filename # fayl nomi
except UnicodeDecodeError as e:
e.encoding, e.object, e.start, e.end, e.reason
except subprocess.CalledProcessError as e:
e.returncode, e.output, e.stderr2.5. EAFP vs LBYL
LBYL — "Look Before You Leap":
if os.path.exists(yol): # ⚠️ tekshiruv
with open(yol) as f: # ⚠️ shu orada fayl o'chishi mumkin
...EAFP — "Easier to Ask Forgiveness than Permission":
try:
with open(yol) as f: # ✅ atomik
...
except FileNotFoundError:
...Uch sabab EAFP foydasiga:
- Poyga holati yo'q — tekshiruv va amal orasida holat o'zgarmaydi
- Tezroq — istisno kamdan-kam bo'lsa (
trydeyarli bepul) - Qisqaroq — bitta tekshiruv o'rniga
LBYL qachon yaxshi:
# 1. Istisno TEZ-TEZ bo'lsa
if k in d: # ✅ 50% hollarda yo'q bo'lsa
...
# 2. Bir necha shart
if x and y and z.mavjud: # ✅ o'qiladigan
# 3. Yon ta'sirni oldini olish
if hajm_yetarlimi(): # ✅ yozishdan oldin
yoz(katta_malumot)Tezlik solishtiruvi:
Python 3.14, lug'atdan o'qish (bitta amal):
try/except if + []
Kalit BOR ~87 ns ~131 ns ⭐ EAFP ~1.5× TEZ
Kalit YO'Q ~336 ns ~87 ns ⚠️ EAFP ~4× sekin Kalit bor bo'lsa EAFP hatto tezroq — LBYL da kalit ikki marta qidiriladi (in va []), EAFP da bir marta. Python 3.11+ da try blokiga kirish deyarli bepul ("zero-cost"), qimmat narsa — istisnoni ko'tarish va ushlash.
Ya'ni: xato kamdan-kam bo'lsa — EAFP; tez-tez bo'lsa — LBYL.
2.6. Ichma-ich va qayta ko'tarish
try:
try:
xavfli()
except ValueError:
tuzat() # ichki
raise # ⭐ QAYTA ko'tarish
except ValueError as e:
logging.error("Tuzatib bo'lmadi: %s", e) raise (argumentsiz) — asl traceback saqlanadi:
except ValueError:
tozala()
raise # ✅ asl traceback
except ValueError as e:
raise e # ⚠️ ishlaydi, lekin ortiqcha traceback yozuvi "raise e traceback'ni yo'qotadi" degan gap Python 2 dan qolgan. Python 3 da asl iz saqlanadi, faqat raise e qatori uchun qo'shimcha yozuv paydo bo'ladi (batafsil — 9.5-dars).
Shartli ushlash:
except OSError as e:
if e.errno != errno.ENOENT:
raise # ⭐ boshqasini uzatamiz
# faqat "fayl yo'q" ni ishlaymiz2.7. Antipatternlar
# ❌ 1. Yalang'och except
except: ...
# ❌ 2. Jimgina yutish
except Exception:
pass # ⚠️ xato yo'qoldi
# ❌ 3. print bilan
except Exception as e:
print(f"Xato: {e}") # ⚠️ traceback yo'q, jurnal yo'q
# ❌ 4. Juda keng try
try:
a = f()
b = g()
c = h() # ⚠️ qaysi biri buzildi?
except Exception:
...
# ❌ 5. Nazorat oqimi sifatida
try:
return d[k]
except KeyError:
return sukut # ⚠️ d.get(k, sukut) yaxshiroq
# (agar tez-tez bo'lsa)
# ❌ 6. Xatoni o'zgartirmasdan qayta ko'tarish
except ValueError as e:
raise e # ⚠️ raise yetadi3. Tez ma'lumotnoma
Sintaksis
try:
xavfli()
except ValueError as e: aniq tur
except (TypeError, KeyError): bir nechta
except Exception as e: ⚠️ faqat yuqori darajada
except: ❌ HECH QACHONYalang'och except
except: ≡ except BaseException:
Ushlaydi:
KeyboardInterrupt ⚠️ Ctrl+C ishlamaydi
SystemExit ⚠️ sys.exit() to'siladi
GeneratorExit ⚠️
+ barcha typo larTartib
except JSONDecodeError: ⭐ AVLOD avval
except ValueError: keyin ota-sinf
⚠️ Teskari bo'lsa — avlod HECH QACHON ishlamaydiEAFP vs LBYL
EAFP (try/except) xato KAMDAN-KAM bo'lsa ⭐ Pythoncha
LBYL (if) xato TEZ-TEZ bo'lsa
Istisno bo'lmasa: try tezroq yoki teng (qidiruv bir marta)
Istisno bo'lsa: try ~4× sekinroq (ko'tarish qimmat)Qayta ko'tarish
raise ✅ asl traceback, toza
raise e ⚠️ asl traceback + ortiqcha yozuv
raise X("...") from e ✅ o'rash4. Batafsil misollar
Misol 1 — Mexanizm va tartib
"""try/except qanday ishlaydi."""
import json
import sys
import traceback
print("=== 1. Bajarilish tartibi ===\n")
def kuzatuv(xatoli: bool):
izlar = []
try:
izlar.append("try boshi")
if xatoli:
1 / 0
izlar.append("try oxiri") # ⚠️ xato bo'lsa bajarilmaydi
except ZeroDivisionError:
izlar.append("except")
izlar.append("keyin")
return izlar
print(f" Xatosiz: {kuzatuv(False)}")
print(f" Xato: {kuzatuv(True)}")
print(f"""
⭐ TARTIB:
1. try bloki boshlanadi
2. Xato bo'lsa → try ning QOLGAN qismi BAJARILMAYDI
3. except turlari TARTIB bilan tekshiriladi
4. Birinchi MOS keladigani bajariladi
5. Hech biri mos kelmasa → yuqoriga uzatiladi
""")
print("=== ⭐ 2. Tur tanlash tartibi ===\n")
def tahlil(matn: str, tartib: str = "togri"):
"""JSON tahlil qilish — turli except tartibi bilan."""
if tartib == "togri":
try:
return ("✅", json.loads(matn))
except json.JSONDecodeError as e: # ⭐ AVLOD avval
return ("JSONDecodeError", str(e)[:30])
except ValueError as e:
return ("ValueError", str(e)[:30])
else:
try:
return ("✅", json.loads(matn))
except ValueError as e: # ⚠️ OTA-SINF avval
return ("ValueError", str(e)[:30])
except json.JSONDecodeError as e: # ❌ hech qachon
return ("JSONDecodeError", str(e)[:30])
MATNLAR = ['{"a": 1}', "{buzilgan}", "[1, 2]", "not json"]
print(f" {'Kirish':<16} {'To`g`ri tartib':<24} {'Noto`g`ri tartib'}")
print(" " + "─" * 66)
for m in MATNLAR:
t1 = tahlil(m, "togri")
t2 = tahlil(m, "notogri")
print(f" {m:<16} {t1[0]:<24} {t2[0]}")
print(f"""
⭐ JSONDecodeError.__mro__:
{[c.__name__ for c in json.JSONDecodeError.__mro__[:4]]}
⚠️ ValueError avval yozilsa — JSONDecodeError bloki
HECH QACHON ishlamaydi (o'lik kod).
✅ QOIDA: ANIQDAN UMUMIYGA
""")
print("=== ⚠️ 3. Yalang'och except ===\n")
print(f" BaseException ierarxiyasi:\n")
IERARXIYA = [
(BaseException, 0),
(SystemExit, 1),
(KeyboardInterrupt, 1),
(GeneratorExit, 1),
(Exception, 1),
(ValueError, 2),
(TypeError, 2),
(LookupError, 2),
(KeyError, 3),
(IndexError, 3),
]
for X, daraja in IERARXIYA:
belgi = "⚠️" if daraja == 1 and X is not Exception else " "
print(f" {' ' * daraja}{'└── ' if daraja else ''}"
f"{X.__name__:<22} {belgi}")
print(f"\n ⚠️ except: — BaseException ni ushlaydi\n")
def yalangoch_test(istisno):
"""Yalang'och except nima ushlaydi."""
try:
raise istisno
except:
return "ushlandi"
def exception_test(istisno):
try:
raise istisno
except Exception:
return "ushlandi"
except BaseException:
return "o'tdi"
ISTISNOLAR = [
ValueError("test"),
KeyError("test"),
KeyboardInterrupt(),
SystemExit(1),
GeneratorExit(),
MemoryError(),
]
print(f" {'Istisno':<24} {'except:':<16} {'except Exception:'}")
print(" " + "─" * 60)
for e in ISTISNOLAR:
try:
r1 = yalangoch_test(e)
except BaseException:
r1 = "o'tdi"
try:
r2 = exception_test(e)
except BaseException:
r2 = "✅ o'tdi"
belgi = "⚠️" if r1 == "ushlandi" and r2 != "ushlandi" else ""
print(f" {type(e).__name__:<24} {r1:<16} {r2} {belgi}")
print(f"""
⚠️ HAQIQIY MUAMMOLAR:
1. Ctrl+C ishlamaydi:
while True:
try: ish()
except: continue ⚠️ cheksiz tsikl
2. sys.exit() to'siladi:
try: sys.exit(1)
except: pass ⚠️ dastur to'xtamaydi
3. Typo yashiriladi:
try: natija = hisoblaa(x) ⚠️ NameError
except: natija = 0 ⚠️ jimgina
4. MemoryError yashiriladi:
⚠️ Xotira tugagan, lekin dastur davom etadi
""")
print("=== 4. Typo ni yashirish ===\n")
def yomon(m):
try:
return sum(m) / lenn(m) # ⚠️ typo: lenn
except:
return 0
def yaxshi(m):
try:
return sum(m) / lenn(m) # ⚠️ typo
except (TypeError, ZeroDivisionError):
return 0
print(f" yomon([1, 2, 3]) = {yomon([1, 2, 3])} "
f"⚠️ 0 — lekin typo bor!")
try:
yaxshi([1, 2, 3])
except NameError as e:
print(f" yaxshi([1, 2, 3]) → ✅ NameError: {e}")
print(f"""
⭐ ANIQ turlar typo larni OCHIB BERADI.
Yalang'och except — ularni YASHIRADI.
""")
print("=== 5. as e va istisno obyekti ===\n")
def xato_tahlili(f, nom: str):
try:
f()
except Exception as e:
print(f" {nom}:")
print(f" type(e) = {type(e).__name__}")
print(f" str(e) = {str(e)!r}")
print(f" repr(e) = {repr(e)}")
print(f" e.args = {e.args}")
maxsus = [a for a in dir(e)
if not a.startswith("_") and a != "args"
and a not in ("with_traceback", "add_note")]
if maxsus:
print(f" maxsus = {maxsus}")
for a in maxsus[:3]:
try:
print(f" e.{a:<12} = {getattr(e, a)!r}")
except Exception:
pass
print()
xato_tahlili(lambda: 1 / 0, "ZeroDivisionError")
xato_tahlili(lambda: {"a": 1}["b"], "KeyError")
xato_tahlili(lambda: open("mavjud_emas_9999.txt"), "FileNotFoundError")
xato_tahlili(lambda: "O'zbek".encode("ascii"), "UnicodeEncodeError")
print(f" ⚠️ e blok TASHQARISIDA yo'q:\n")
try:
1 / 0
except ZeroDivisionError as e:
ichkarida = str(e)
try:
print(e)
except NameError as err:
print(f" print(e) → ✅ NameError: {err}")
print(f" Ichkarida: {ichkarida!r}")
print(f"""
⭐ SABAB: Python 3 da except bloki oxirida
avtomatik `del e` bajariladi.
Sabab — aylanma havola:
e → __traceback__ → ramka → lokal → e
✅ Saqlash kerak bo'lsa:
xato = None
try: ...
except ValueError as e:
xato = e ⭐ boshqa nomga
""")
print("=== ⭐ 6. add_note (3.11+) ===\n")
try:
try:
1 / 0
except ZeroDivisionError as e:
e.add_note("Kontekst: hisobot yasashda") # ⭐ 3.11+
e.add_note("Foydalanuvchi: aziz@wisar.uz")
raise
except ZeroDivisionError as e:
print(f" Izohlar: {e.__notes__}")
print(f"\n Traceback da:")
for q in traceback.format_exc().rstrip().split("\n"):
print(f" {q}")
print(f"""
⭐ add_note() — istisnoni O'ZGARTIRMASDAN kontekst qo'shadi.
Traceback da avtomatik ko'rinadi.
⚠️ Python 3.11+ (PEP 678)
""")Natijaning muhim qismi:
=== 1. Bajarilish tartibi ===
Xatosiz: ['try boshi', 'try oxiri', 'keyin']
Xato: ['try boshi', 'except', 'keyin']
=== ⭐ 2. Tur tanlash tartibi ===
Kirish To`g`ri tartib Noto`g`ri tartib
──────────────────────────────────────────────────────────────────
{"a": 1} ✅ ✅
{buzilgan} JSONDecodeError ValueError
not json JSONDecodeError ValueError
=== ⚠️ 3. Yalang'och except ===
Istisno except: except Exception:
────────────────────────────────────────────────────────────
ValueError ushlandi ushlandi
KeyboardInterrupt ushlandi o'tdi ⚠️
SystemExit ushlandi o'tdi ⚠️
=== 4. Typo ni yashirish ===
yomon([1, 2, 3]) = 0 ⚠️ 0 — lekin typo bor!
yaxshi([1, 2, 3]) → ✅ NameError: name 'lenn' is not definedNima ko'rsatdi: 2.1, 2.2, 2.3, 2.4-bo'limlar.
Misol 2 — EAFP vs LBYL
"""Ikki uslub: qachon qaysi biri."""
from __future__ import annotations
import os
import time
import timeit
from pathlib import Path
print("=== ⭐ 1. Poyga holati ===\n")
print(""" ⚠️ LBYL — poyga holati (race condition):
if os.path.exists(yol): # 1. tekshiruv
# ⚠️ SHU YERDA boshqa jarayon faylni O'CHIRISHI mumkin
with open(yol) as f: # 2. ochish
... # ❌ FileNotFoundError
✅ EAFP — atomik:
try:
with open(yol) as f: # ⭐ bitta amal
...
except FileNotFoundError:
...
⭐ Boshqa poyga holatlari:
• Fayl ruxsatlari o'zgaradi
• Lug'at boshqa ipchada o'zgaradi
• Tarmoq ulanishi uziladi
• Disk to'ladi
""")
print("=== 2. Tezlik solishtiruvi ===\n")
LUGAT = {f"kalit{i}": i for i in range(1000)}
N = 500_000
def lbyl_bor(d, k):
if k in d:
return d[k]
return None
def eafp_bor(d, k):
try:
return d[k]
except KeyError:
return None
print(f" {N:,} chaqiruv:\n")
print(f" {'Holat':<24} {'LBYL':>10} {'EAFP':>10} {'Farq'}")
print(" " + "─" * 56)
HOLATLAR = [
("Kalit BOR (100%)", "kalit500"),
("Kalit YO'Q (100%)", "mavjud_emas"),
]
for nom, k in HOLATLAR:
t1 = timeit.timeit(lambda: lbyl_bor(LUGAT, k), number=N)
t2 = timeit.timeit(lambda: eafp_bor(LUGAT, k), number=N)
farq = f"{t2/t1:.1f}× sekin" if t2 > t1 else f"{t1/t2:.1f}× tez"
print(f" {nom:<24} {t1:>8.3f}s {t2:>9.3f}s EAFP {farq}")
# Aralash holat
import random
random.seed(42)
KALITLAR = ([f"kalit{i}" for i in range(950)]
+ [f"yoq{i}" for i in range(50)])
random.shuffle(KALITLAR)
def lbyl_aralash():
for k in KALITLAR:
lbyl_bor(LUGAT, k)
def eafp_aralash():
for k in KALITLAR:
eafp_bor(LUGAT, k)
t1 = timeit.timeit(lbyl_aralash, number=500)
t2 = timeit.timeit(eafp_aralash, number=500)
print(f" {'5% xato (aralash)':<24} {t1:>8.3f}s {t2:>9.3f}s "
f"EAFP {t2/t1:.2f}×")
KALITLAR2 = ([f"kalit{i}" for i in range(500)]
+ [f"yoq{i}" for i in range(500)])
random.shuffle(KALITLAR2)
def lbyl2():
for k in KALITLAR2: lbyl_bor(LUGAT, k)
def eafp2():
for k in KALITLAR2: eafp_bor(LUGAT, k)
t1 = timeit.timeit(lbyl2, number=500)
t2 = timeit.timeit(eafp2, number=500)
print(f" {'50% xato':<24} {t1:>8.3f}s {t2:>9.3f}s "
f"EAFP {t2/t1:.2f}×")
print(f"""
⭐ XULOSA:
Xato YO'Q → try/except deyarli BEPUL (hatto tezroq)
Xato BOR → try/except bir necha marta sekinroq
5% xato → farq kichik
50% xato → LBYL sezilarli tezroq
⭐ QOIDA: istisno ISTISNO bo'lsin (kamdan-kam).
""")
print("=== 3. Amaliy holatlar ===\n")
print(""" ✅ EAFP TO'G'RI:
# 1. Fayl bilan ishlash (poyga holati)
try:
with open(yol) as f: ...
except FileNotFoundError: ...
# 2. Tur o'girish
try:
n = int(matn)
except ValueError:
n = 0
# 3. Atribut (duck typing)
try:
return obj.metod()
except AttributeError:
return sukut
# 4. Tarmoq
try:
javob = sorov(url)
except ConnectionError: ...
# 5. Import (ixtiyoriy bog'liqlik)
try:
import ujson as json
except ImportError:
import json
✅ LBYL TO'G'RI:
# 1. Xato TEZ-TEZ
if k in d: ... # 50% hollarda yo'q
# 2. Bir necha shart
if x and y and z > 0: ...
# 3. Yon ta'sirni oldini olish
if bosh_joy() > kerak:
yoz(katta_malumot) # ⚠️ yozib, keyin xato — yomon
# 4. Oddiy tekshiruv
if lst: ... # try/except ortiqcha
""")
print("=== ⭐ 4. Tayyor muqobillar ===\n")
d = {"a": 1}
lst = [1, 2, 3]
s = {1, 2}
MUQOBILLAR = [
("d[k]", "d.get(k, sukut)",
lambda: d.get("yoq", "sukut")),
("d.pop(k)", "d.pop(k, sukut)",
lambda: d.pop("yoq", "sukut")),
("s.remove(x)", "s.discard(x)",
lambda: s.discard(99)),
("next(it)", "next(it, sukut)",
lambda: next(iter([]), "sukut")),
("lst[i]", "lst[i:i+1]",
lambda: lst[99:100]),
("int(x)", "⚠️ muqobil yo'q — try kerak", None),
("getattr(o, n)", "getattr(o, n, sukut)",
lambda: getattr(d, "yoq", "sukut")),
("os.remove(p)", "Path(p).unlink(missing_ok=True)", None),
("os.mkdir(p)", "Path(p).mkdir(exist_ok=True)", None),
("d[k] += 1", "defaultdict / Counter", None),
]
print(f" {'Xatoli':<22} {'Xavfsiz muqobil':<38} {'Natija'}")
print(" " + "─" * 74)
for xatoli, xavfsiz, f in MUQOBILLAR:
natija = repr(f()) if f else "—"
print(f" {xatoli:<22} {xavfsiz:<38} {natija}")
print(f"""
⭐ MUQOBIL BO'LSA — UNI ISHLATING:
d.get(k, sukut) ✅ oddiyroq va tezroq
try: d[k] ⚠️ ortiqcha
⚠️ LEKIN: agar YO'Q bo'lish HAQIQATAN xato bo'lsa —
try/except aniqroq niyatni bildiradi.
""")
print("=== 5. Aralash yondashuv ===\n")
def sozlama_oqi_lbyl(yol: str) -> dict:
"""⚠️ Ko'p tekshiruv."""
import json
if not os.path.exists(yol):
return {}
if not os.path.isfile(yol):
return {}
if not os.access(yol, os.R_OK):
return {}
if os.path.getsize(yol) == 0:
return {}
with open(yol, encoding="utf-8") as f:
matn = f.read()
if not matn.strip():
return {}
try:
m = json.loads(matn)
except json.JSONDecodeError:
return {}
return m if isinstance(m, dict) else {}
def sozlama_oqi_eafp(yol: str) -> dict:
"""✅ Qisqa va atomik."""
import json
try:
with open(yol, encoding="utf-8") as f:
m = json.load(f)
return m if isinstance(m, dict) else {}
except (OSError, json.JSONDecodeError, UnicodeDecodeError):
return {}
print(f" LBYL versiyasi: {len(sozlama_oqi_lbyl.__code__.co_code)} bayt-kod")
print(f" EAFP versiyasi: {len(sozlama_oqi_eafp.__code__.co_code)} bayt-kod")
import inspect
q1 = len(inspect.getsource(sozlama_oqi_lbyl).split("\n"))
q2 = len(inspect.getsource(sozlama_oqi_eafp).split("\n"))
print(f"\n Kod qatorlari: {q1} vs {q2}")
print(f"\n Sinov:")
import tempfile, json as _json
with tempfile.TemporaryDirectory() as tmp:
p = Path(tmp)
(p / "yaxshi.json").write_text('{"a": 1}', encoding="utf-8")
(p / "buzilgan.json").write_text("{buzilgan}", encoding="utf-8")
(p / "bosh.json").write_text("", encoding="utf-8")
(p / "royxat.json").write_text("[1, 2]", encoding="utf-8")
SINOVLAR = ["yaxshi.json", "buzilgan.json", "bosh.json",
"royxat.json", "yoq.json", "."]
print(f" {'Fayl':<18} {'LBYL':<12} {'EAFP'}")
print(" " + "─" * 44)
for nom in SINOVLAR:
yol = str(p / nom) if nom != "." else str(p)
try:
r1 = repr(sozlama_oqi_lbyl(yol))
except Exception as e:
r1 = f"❌ {type(e).__name__}"
try:
r2 = repr(sozlama_oqi_eafp(yol))
except Exception as e:
r2 = f"❌ {type(e).__name__}"
print(f" {nom:<18} {r1:<12} {r2}")
print(f"""
⭐ EAFP:
• {q2} qator ({q1} o'rniga)
• Poyga holati yo'q
• Barcha holatlarni qamraydi
• Yangi xato turi qo'shilsa — except ga qo'shiladi
⚠️ LBYL:
• Har tekshiruv — poyga holati
• Ba'zi holatlar unutiladi (papka, ruxsat, kodlash)
• Uzunroq
""")
print("=== 6. Poyga holati: tekshiruv va foydalanish orasidagi oyna ===\n")
class BoshqaIpchaBilan(dict):
"""⭐ "Boshqa ipcha"ni DETERMINISTIK simulyatsiya qiladi.
Real ipchalarda o'chirish aynan tekshiruv va foydalanish orasiga
tushishi KAMDAN-KAM bo'ladi. Bu yerda biz uni ataylab o'sha
lahzaga qo'yamiz — xato har safar takrorlanadi.
"""
def __contains__(self, kalit):
bor = super().__contains__(kalit)
self.pop(kalit, None) # ⚠️ shu lahzada boshqa ipcha o'chirdi
return bor
def lbyl_ol(d, kalit):
if kalit in d: # 1. tekshiruv — "bor"
return d[kalit] # 2. ⚠️ endi yo'q!
return "yo'q"
def eafp_ol(d, kalit):
try:
return d[kalit] # ⭐ bitta amal
except KeyError:
return "yo'q"
for nom, f in [("LBYL (if + [])", lbyl_ol), ("EAFP (try)", eafp_ol)]:
d = BoshqaIpchaBilan(sessiya="abc123")
try:
natija = repr(f(d, "sessiya"))
except KeyError as e:
natija = f"❌ KeyError: {e} ⚠️ POYGA HOLATI"
print(f" {nom:<16} → {natija}")
print(f"""
⭐ LBYL da `if k in d` VA `d[k]` — IKKI amal.
Ular orasida holat o'zgarishi mumkin ("TOCTOU": time of check
to time of use). Tekshiruv "bor" dedi — foydalanish paytida yo'q.
⭐ EAFP da `d[k]` — BITTA amal. Natija yoki qiymat, yoki KeyError —
ikkalasi ham HAQIQIY holatni aks ettiradi.
⚠️ Nega real ipchalar bilan ko'rsatmadik? Chunki bunday xato
juda kamdan-kam va tasodifiy chiqadi: CPython da GIL ipchalarni
millisekundlab navbatma-navbat ishlatadi, va o'chirish aynan shu
ikki amal orasiga tushishi uchun omad kerak. Aynan shuning uchun
u XAVFLI — testlarda o'tadi, ishlab chiqarishda esa bir kun
kutilmaganda qulaydi. Fayl tizimi, tarmoq va bazada (bir nechta
jarayon ishlaganda) bu oyna ancha katta.
""")Natijaning muhim qismi:
=== 2. Tezlik solishtiruvi ===
500,000 chaqiruv:
Holat LBYL EAFP Farq
────────────────────────────────────────────────────────
Kalit BOR (100%) 0.111s 0.083s EAFP 1.3× tez
Kalit YO'Q (100%) 0.094s 0.268s EAFP 2.8× sekin
5% xato (aralash) 0.098s 0.112s EAFP 1.14×
50% xato 0.089s 0.245s EAFP 2.75×
=== ⭐ 4. Tayyor muqobillar ===
Xatoli Xavfsiz muqobil Natija
──────────────────────────────────────────────────────────────────────────
d[k] d.get(k, sukut) 'sukut'
next(it) next(it, sukut) 'sukut'
lst[i] lst[i:i+1] []
=== 6. Poyga holati: tekshiruv va foydalanish orasidagi oyna ===
LBYL (if + []) → ❌ KeyError: 'sessiya' ⚠️ POYGA HOLATI
EAFP (try) → 'abc123'Nima ko'rsatdi: 2.5-bo'lim.
Misol 3 — Qayta ko'tarish va ichma-ich
"""raise, ichma-ich try va shartli ushlash."""
from __future__ import annotations
import errno
import os
import time
import traceback
from pathlib import Path
print("=== ⭐ 1. raise vs raise e ===\n")
def ichki():
1 / 0
def orta_raise():
try:
ichki()
except ZeroDivisionError:
raise # ⭐ asl traceback
def orta_raise_e():
try:
ichki()
except ZeroDivisionError as e:
raise e # ⚠️ ortiqcha yozuv
def orta_raise_new():
try:
ichki()
except ZeroDivisionError as e:
raise RuntimeError("Yangi") from e # ⭐ zanjir
for f, nom in [(orta_raise, "raise"), (orta_raise_e, "raise e"),
(orta_raise_new, "raise X from e")]:
try:
f()
except Exception as e:
ramkalar = len(traceback.extract_tb(e.__traceback__))
print(f" {nom:<20} {ramkalar} ramka, "
f"{type(e).__name__}")
for q in traceback.format_exc().rstrip().split("\n")[-6:]:
print(f" {q}")
print()
print(f""" ⭐ FARQI:
raise asl traceback saqlanadi
raise e asl traceback ham saqlanadi, lekin "raise e"
qatori uchun BITTA ortiqcha ramka qo'shiladi
raise X from e yangi istisno + asl sabab zanjirda (__cause__)
""")
print("=== ⭐ 2. Shartli ushlash ===\n")
def fayl_ochir(yol: str) -> bool:
"""⭐ Faqat 'fayl yo'q' xatosini yutamiz."""
try:
os.remove(yol)
return True
except OSError as e:
if e.errno != errno.ENOENT: # ⭐ boshqasini uzatamiz
raise
return False
import tempfile
with tempfile.TemporaryDirectory() as tmp:
p = Path(tmp)
(p / "bor.txt").write_text("test")
print(f" fayl_ochir(mavjud fayl) = {fayl_ochir(str(p / 'bor.txt'))}")
print(f" fayl_ochir(mavjud emas) = {fayl_ochir(str(p / 'yoq.txt'))}")
try:
fayl_ochir(str(p)) # ⚠️ papka
except OSError as e:
print(f" fayl_ochir(papka) → ✅ {type(e).__name__}: "
f"errno={e.errno}")
print(f"""
⭐ NAQSH:
except OSError as e:
if e.errno != KUTILGAN:
raise ⭐ boshqasini uzatamiz
# faqat kutilganini ishlaymiz
⭐ Muqobil (3.3+):
except FileNotFoundError: ✅ aniqroq
""")
print("=== 3. Ichma-ich try ===\n")
def ichma_ich(bosqich_xato: int):
"""Uch bosqichli quvur — har birida tozalash."""
izlar = []
try:
izlar.append("1: resurs ochildi")
if bosqich_xato == 1:
raise ValueError("1-bosqich")
try:
izlar.append("2: ma'lumot yuklandi")
if bosqich_xato == 2:
raise KeyError("2-bosqich")
try:
izlar.append("3: qayta ishlandi")
if bosqich_xato == 3:
raise TypeError("3-bosqich")
izlar.append("✅ muvaffaqiyat")
except TypeError as e:
izlar.append(f" 3-tozalash: {e}")
raise # ⭐ yuqoriga
except KeyError as e:
izlar.append(f" 2-tozalash: {e}")
raise
except (ValueError, KeyError, TypeError) as e:
izlar.append(f" 1-tozalash: {type(e).__name__}")
izlar.append(f"❌ yakuniy: {e}")
return izlar
for n in [0, 1, 2, 3]:
print(f" Xato {n}-bosqichda:" if n else " Xatosiz:")
for q in ichma_ich(n):
print(f" {q}")
print()
print(f""" ⭐ HAR DARAJADA:
• O'z tozalashini bajaradi
• raise bilan yuqoriga uzatadi
• Asl istisno saqlanadi
⚠️ Bu naqsh uchun `finally` yoki `with` yaxshiroq (9.3-dars)
""")
print("=== ⭐ 4. Qayta urinish naqshi ===\n")
class VaqtinchalikXato(Exception):
"""Qayta urinish mumkin."""
class DoimiyXato(Exception):
"""Qayta urinish foydasiz."""
def notogri_xizmat(urinish: int, holat: list):
"""Uchinchi urinishda ishlaydi."""
holat[0] += 1
if holat[0] < 3:
raise VaqtinchalikXato(f"Tarmoq xatosi (urinish {holat[0]})")
return f"✅ Natija (urinish {holat[0]})"
def qayta_urin(f, urinishlar: int = 5, kutish: float = 0.001,
qayta_urinilsin: tuple = (VaqtinchalikXato,)):
"""⭐ Faqat MA'LUM xatolarda qayta urinadi."""
oxirgi = None
for n in range(1, urinishlar + 1):
try:
return f(n)
except qayta_urinilsin as e: # ⭐ vaqtinchalik
oxirgi = e
if n < urinishlar:
time.sleep(kutish * (2 ** (n - 1))) # eksponensial
except Exception:
raise # ⭐ boshqasi — darhol
raise RuntimeError(
f"{urinishlar} urinish muvaffaqiyatsiz"
) from oxirgi
holat = [0]
natija = qayta_urin(lambda n: notogri_xizmat(n, holat))
print(f" Vaqtinchalik xato: {natija}")
holat = [0]
try:
qayta_urin(lambda n: notogri_xizmat(n, holat), urinishlar=2)
except RuntimeError as e:
print(f"\n Urinishlar yetmadi:")
print(f" ❌ {e}")
print(f" Sabab: {type(e.__cause__).__name__}: {e.__cause__}")
def doimiy_xato(n):
raise DoimiyXato("Autentifikatsiya xatosi")
print(f"\n Doimiy xato (qayta urinilmaydi):")
try:
qayta_urin(doimiy_xato)
except DoimiyXato as e:
print(f" ✅ {type(e).__name__}: {e} (darhol, urinishsiz)")
print(f"""
⭐ QAYTA URINISH QOIDALARI:
✅ Qayta urinish MUMKIN:
ConnectionError, TimeoutError, 429/503 javoblar,
vaqtinchalik baza xatolari
❌ Qayta urinish FOYDASIZ:
ValueError, TypeError, autentifikatsiya, 400/404,
dastur mantiqidagi xato
⭐ Eksponensial kutish: 1ms, 2ms, 4ms, 8ms, ...
""")
print("=== 5. Bir necha xatoni yig'ish ===\n")
def quvur(malumot: list) -> tuple[list, list]:
"""⭐ Xato bo'lsa TO'XTAMAYDI — yig'adi."""
natija, xatolar = [], []
for i, x in enumerate(malumot):
try:
natija.append(int(x) * 2)
except (ValueError, TypeError) as e:
xatolar.append((i, x, e))
return natija, xatolar
MALUMOT = [1, "2", "uch", 4.5, None, "6", [7]]
natija, xatolar = quvur(MALUMOT)
print(f" Kirish: {MALUMOT}\n")
print(f" ✅ Natija ({len(natija)}): {natija}")
print(f"\n ❌ Xatolar ({len(xatolar)}):")
for i, x, e in xatolar:
print(f" [{i}] {x!r:<10} {type(e).__name__}: {str(e)[:38]}")
print(f"\n ⭐ ExceptionGroup (3.11+):")
import sys
if sys.version_info >= (3, 11):
try:
raise ExceptionGroup(
"Quvurda xatolar",
[e for _, _, e in xatolar],
)
except* ValueError as eg:
print(f" ValueError guruhi: {len(eg.exceptions)} ta")
except* TypeError as eg:
print(f" TypeError guruhi: {len(eg.exceptions)} ta")
else:
print(f" ⚠️ Python 3.11+ kerak "
f"(joriy: {sys.version_info.major}.{sys.version_info.minor})")
print(f"""
⭐ ExceptionGroup (PEP 654, 3.11):
• Bir nechta istisnoni BIRGA ko'tarish
• except* bilan turlar bo'yicha ajratish
• asyncio.TaskGroup ishlatadi
""")
print("=== ⭐ 6. Kontekst qo'shish ===\n")
def sozlama_yukla(yol: str) -> dict:
import json
try:
with open(yol, encoding="utf-8") as f:
return json.load(f)
except FileNotFoundError as e:
raise RuntimeError(
f"Sozlama fayli topilmadi: {yol}"
) from e
except json.JSONDecodeError as e:
raise RuntimeError(
f"Sozlama fayli buzilgan: {yol} "
f"(qator {e.lineno}, ustun {e.colno})"
) from e
except PermissionError as e:
raise RuntimeError(
f"Sozlama fayliga ruxsat yo'q: {yol}"
) from e
with tempfile.TemporaryDirectory() as tmp:
p = Path(tmp)
(p / "buzilgan.json").write_text('{"a": 1,\n "b": }',
encoding="utf-8")
for nom in ["yoq.json", "buzilgan.json"]:
try:
sozlama_yukla(str(p / nom))
except RuntimeError as e:
print(f" {nom}:")
print(f" ❌ {e}")
print(f" Sabab: {type(e.__cause__).__name__}")
print(f"""
⭐ KONTEKST QO'SHISH NAQSHI:
except AniqXato as e:
raise UmumiyXato(
f"Nima bo'lgani + QAYERDA + QANDAY tuzatish"
) from e
⭐ AFZALLIKLARI:
• Foydalanuvchi tushunadi
• Asl sabab saqlanadi (from e)
• Ichki tafsilotlar yashiriladi
• Yuqori qatlam bitta tur bilan ishlaydi
""")Natijaning muhim qismi:
=== ⭐ 1. raise vs raise e ===
raise 3 ramka, ZeroDivisionError
raise e 4 ramka, ZeroDivisionError
raise X from e 2 ramka, RuntimeError
=== ⭐ 4. Qayta urinish naqshi ===
Vaqtinchalik xato: ✅ Natija (urinish 3)
Urinishlar yetmadi:
❌ 2 urinish muvaffaqiyatsiz
Sabab: VaqtinchalikXato: Tarmoq xatosi (urinish 2)
Doimiy xato (qayta urinilmaydi):
✅ DoimiyXato: Autentifikatsiya xatosi (darhol, urinishsiz)
=== 5. Bir necha xatoni yig'ish ===
✅ Natija (4): [2, 4, 8, 12]
❌ Xatolar (3):
[2] 'uch' ValueError: invalid literal for int()
[4] None TypeError: int() argument must be a stringNima ko'rsatdi: 2.6, 2.7-bo'limlar.
Misol 4 — Amaliy: ishonchli ma'lumot yuklovchi
"""try/except ning barcha jihatlari bir loyihada."""
from __future__ import annotations
import csv
import io
import json
import logging
import time
from dataclasses import dataclass, field
from datetime import datetime, date
from decimal import Decimal, InvalidOperation
from pathlib import Path
from typing import Any, Callable, Iterator
print("=== MA'LUMOT YUKLOVCHI ===\n")
jurnal = logging.getLogger("yuklovchi")
jurnal.setLevel(logging.DEBUG)
_bufer = io.StringIO()
_h = logging.StreamHandler(_bufer)
_h.setFormatter(logging.Formatter("%(levelname)-8s %(message)s"))
jurnal.addHandler(_h)
jurnal.propagate = False
# ═══ ISTISNOLAR ═══
class YuklashXatosi(Exception):
"""Asosiy — foydalanuvchiga ko'rsatiladi."""
class VaqtinchalikXato(YuklashXatosi):
"""⭐ Qayta urinish mumkin."""
class MalumotXatosi(YuklashXatosi):
"""⭐ Ma'lumot yaroqsiz — qayta urinish foydasiz."""
def __init__(self, xabar: str, qator: int = 0, ustun: str = ""):
self.qator, self.ustun = qator, ustun
joy = []
if qator:
joy.append(f"qator {qator}")
if ustun:
joy.append(f"ustun {ustun!r}")
super().__init__(f"{xabar} ({', '.join(joy)})" if joy else xabar)
# ═══ NATIJA ═══
@dataclass
class Natija:
"""Yuklash natijasi."""
yozuvlar: list[dict] = field(default_factory=list)
xatolar: list[tuple[int, Exception]] = field(default_factory=list)
ogohlantirishlar: list[str] = field(default_factory=list)
urinishlar: int = 0
vaqt_ms: float = 0.0
@property
def muvaffaqiyatli(self) -> bool:
return bool(self.yozuvlar) and not self.xatolar
@property
def qisman(self) -> bool:
return bool(self.yozuvlar) and bool(self.xatolar)
def __str__(self):
holat = ("✅ to'liq" if self.muvaffaqiyatli else
"⚠️ qisman" if self.qisman else "❌ muvaffaqiyatsiz")
return (f"{holat}: {len(self.yozuvlar)} yozuv, "
f"{len(self.xatolar)} xato, {self.vaqt_ms:.1f}ms")
# ═══ MAYDON O'GIRUVCHILAR ═══
def satr(q: Any) -> str:
if q is None:
raise ValueError("bo'sh qiymat")
n = str(q).strip()
if not n:
raise ValueError("bo'sh satr")
return n
def butun(q: Any) -> int:
try:
return int(str(q).strip().replace(" ", "").replace(",", ""))
except (ValueError, TypeError) as e:
raise ValueError(f"butun son emas: {q!r}") from e
def pul(q: Any) -> Decimal:
try:
return Decimal(str(q).strip().replace(" ", "").replace(",", ""))
except (InvalidOperation, TypeError) as e:
raise ValueError(f"summa emas: {q!r}") from e
def sana(q: Any) -> date:
matn = str(q).strip()
for fmt in ("%Y-%m-%d", "%d.%m.%Y", "%d/%m/%Y"):
try:
return datetime.strptime(matn, fmt).date()
except ValueError:
continue
raise ValueError(f"sana formati noma'lum: {q!r}")
def mantiq(q: Any) -> bool:
n = str(q).strip().lower()
if n in ("1", "true", "ha", "yes", "y", "+"):
return True
if n in ("0", "false", "yo'q", "yoq", "no", "n", "-", ""):
return False
raise ValueError(f"mantiqiy qiymat emas: {q!r}")
# ═══ YUKLOVCHI ═══
class Yuklovchi:
"""⭐ Ishonchli ma'lumot yuklash."""
SXEMA: dict[str, tuple[Callable, bool]] = {
# nom: (o'giruvchi, majburiy)
"id": (butun, True),
"ism": (satr, True),
"maosh": (pul, True),
"ishga_kirgan": (sana, False),
"faol": (mantiq, False),
}
def __init__(self, *, urinishlar: int = 3, kutish: float = 0.001,
maks_xato: int | None = None, qatiy: bool = False):
self.urinishlar = urinishlar
self.kutish = kutish
self.maks_xato = maks_xato
self.qatiy = qatiy
# ── Bitta yozuv ──
def _yozuv(self, xom: dict, qator: int) -> dict:
"""⭐ Har maydon alohida try — aniq xato joyi."""
natija = {}
for nom, (ogir, majburiy) in self.SXEMA.items():
if nom not in xom or xom[nom] in (None, ""):
if majburiy:
raise MalumotXatosi(
"majburiy maydon yo'q", qator, nom
)
natija[nom] = None
continue
try:
natija[nom] = ogir(xom[nom])
except ValueError as e:
raise MalumotXatosi(str(e), qator, nom) from e
return natija
# ── Manbalar ──
def _csv(self, matn: str) -> Iterator[tuple[int, dict]]:
try:
oquvchi = csv.DictReader(io.StringIO(matn))
for i, q in enumerate(oquvchi, 2):
yield i, q
except csv.Error as e:
raise MalumotXatosi(f"CSV xatosi: {e}") from e
def _json(self, matn: str) -> Iterator[tuple[int, dict]]:
try:
m = json.loads(matn)
except json.JSONDecodeError as e:
raise MalumotXatosi(
f"JSON xatosi: {e.msg}", e.lineno
) from e
if isinstance(m, dict):
m = [m]
if not isinstance(m, list):
raise MalumotXatosi("JSON massiv yoki obyekt bo'lsin")
for i, q in enumerate(m, 1):
if not isinstance(q, dict):
raise MalumotXatosi(f"obyekt kutildi: {type(q).__name__}",
i)
yield i, q
# ── Asosiy ──
def yukla(self, manba: str | Path, format: str = "auto") -> Natija:
"""⭐ Qayta urinish + xatolarni yig'ish."""
boshlanish = time.perf_counter()
n = Natija()
# 1. Manbani o'qish (qayta urinish bilan)
matn = None
for urinish in range(1, self.urinishlar + 1):
n.urinishlar = urinish
try:
matn = self._oqi(manba)
break
except VaqtinchalikXato as e:
jurnal.warning("Urinish %d/%d: %s",
urinish, self.urinishlar, e)
if urinish < self.urinishlar:
time.sleep(self.kutish * (2 ** (urinish - 1)))
except YuklashXatosi:
raise # ⭐ doimiy — darhol
else:
n.vaqt_ms = (time.perf_counter() - boshlanish) * 1000
raise VaqtinchalikXato(
f"{self.urinishlar} urinish muvaffaqiyatsiz"
)
# 2. Formatni aniqlash
if format == "auto":
format = "json" if matn.lstrip()[:1] in "[{" else "csv"
n.ogohlantirishlar.append(f"format aniqlandi: {format}")
# 3. Yozuvlarni qayta ishlash
tahlilchi = {"csv": self._csv, "json": self._json}[format]
try:
for qator, xom in tahlilchi(matn):
try:
n.yozuvlar.append(self._yozuv(xom, qator))
except MalumotXatosi as e:
n.xatolar.append((qator, e))
jurnal.debug("Qator %d: %s", qator, e)
if self.qatiy:
raise
if (self.maks_xato is not None
and len(n.xatolar) >= self.maks_xato):
n.ogohlantirishlar.append(
f"xato chegarasi ({self.maks_xato}) — to'xtatildi"
)
break
except MalumotXatosi as e:
if self.qatiy:
raise
n.xatolar.append((0, e))
n.vaqt_ms = (time.perf_counter() - boshlanish) * 1000
return n
def _oqi(self, manba: str | Path) -> str:
"""⭐ Xatolarni ANIQ turlarga o'giradi."""
if isinstance(manba, str) and (
manba.lstrip()[:1] in "[{" or "," in manba.split("\n")[0]
):
return manba # to'g'ridan-to'g'ri matn
yol = Path(manba)
try:
return yol.read_text(encoding="utf-8")
except FileNotFoundError as e:
raise MalumotXatosi(f"fayl topilmadi: {yol}") from e
except IsADirectoryError as e:
raise MalumotXatosi(f"papka, fayl emas: {yol}") from e
except PermissionError as e:
# ⚠️ Windows'da papkani o'qishga urinish ham PermissionError
# beradi (Linux/macOS da — IsADirectoryError)
if yol.is_dir():
raise MalumotXatosi(f"papka, fayl emas: {yol}") from e
raise MalumotXatosi(f"ruxsat yo'q: {yol}") from e
except UnicodeDecodeError as e:
raise MalumotXatosi(
f"kodlash xatosi ({e.encoding}, bayt {e.start})"
) from e
except OSError as e:
raise VaqtinchalikXato(f"o'qish xatosi: {e}") from e
# ═══ SINOVLAR ═══
CSV_YAXSHI = """id,ism,maosh,ishga_kirgan,faol
1,Aziz Karimov,8500000,2023-03-15,ha
2,Malika Yusupova,7 000 000,15.01.2024,1
3,Bobur Aliyev,9500000,2022-06-01,yo'q"""
CSV_MUAMMOLI = """id,ism,maosh,ishga_kirgan,faol
1,Aziz,8500000,2023-03-15,ha
xato,Malika,7000000,2024-01-15,1
3,,9500000,2022-06-01,ha
4,Dilnoza,ko'p pul,2023-01-01,ha
5,Sardor,6000000,noto'g'ri-sana,ha
6,Nilufar,5500000,2023-05-05,ehtimol
7,Jasur,7500000,2023-07-07,ha"""
JSON_YAXSHI = json.dumps([
{"id": 10, "ism": "Kamola", "maosh": "12000000",
"ishga_kirgan": "2021-09-01", "faol": True},
{"id": 11, "ism": "Rustam", "maosh": "8000000"},
])
JSON_BUZILGAN = '{"id": 1, "ism": }'
print("1. To'liq muvaffaqiyat:\n")
y = Yuklovchi()
n = y.yukla(CSV_YAXSHI)
print(f" {n}\n")
for z in n.yozuvlar:
print(f" {z['id']}. {z['ism']:<18} {z['maosh']:>12,} "
f"{z['ishga_kirgan']} {z['faol']}")
print("\n\n2. ⭐ Qisman muvaffaqiyat (xatolar yig'iladi):\n")
n = y.yukla(CSV_MUAMMOLI)
print(f" {n}\n")
print(f" ✅ Yuklandi ({len(n.yozuvlar)}):")
for z in n.yozuvlar:
print(f" {z['id']}. {z['ism']:<12} {z['maosh']:>12,}")
print(f"\n ❌ Xatolar ({len(n.xatolar)}):")
for qator, e in n.xatolar:
print(f" {e}")
print(f"\n ⭐ Ish TO'XTAMADI — {len(n.xatolar)} xatoga qaramay "
f"{len(n.yozuvlar)} yozuv yuklandi")
print("\n\n3. Xato chegarasi:\n")
for maks in [None, 2, 1]:
y2 = Yuklovchi(maks_xato=maks)
n2 = y2.yukla(CSV_MUAMMOLI)
print(f" maks_xato={str(maks):<6} → {n2}")
if n2.ogohlantirishlar:
for o in n2.ogohlantirishlar:
print(f" ⚠️ {o}")
print("\n\n4. Qat'iy rejim:\n")
y3 = Yuklovchi(qatiy=True)
try:
y3.yukla(CSV_MUAMMOLI)
except MalumotXatosi as e:
print(f" ❌ {type(e).__name__}: {e}")
print(f" qator={e.qator}, ustun={e.ustun!r}")
print(f" sabab: {type(e.__cause__).__name__}: {e.__cause__}")
print("\n\n5. JSON manbasi:\n")
n = y.yukla(JSON_YAXSHI)
print(f" Yaxshi JSON: {n}")
for z in n.yozuvlar:
print(f" {z['id']}. {z['ism']:<10} {z['maosh']:>12,} "
f"sana={z['ishga_kirgan']}")
print(f"\n Buzilgan JSON:")
n = y.yukla(JSON_BUZILGAN)
print(f" {n}")
for _, e in n.xatolar:
print(f" ❌ {e}")
print("\n\n6. ⭐ Fayl xatolari (aniq turlar):\n")
import tempfile
with tempfile.TemporaryDirectory() as tmp:
p = Path(tmp)
(p / "yaxshi.csv").write_text(CSV_YAXSHI, encoding="utf-8")
(p / "buzilgan.csv").write_bytes(b"id,ism\n1,\xff\xfe")
FAYLLAR = [
("yaxshi.csv", "mavjud fayl"),
("yoq.csv", "mavjud emas"),
(".", "papka"),
("buzilgan.csv", "kodlash xatosi"),
]
for nom, tavsif in FAYLLAR:
yol = p / nom if nom != "." else p
try:
n = y.yukla(yol)
r = f"✅ {n}"
except YuklashXatosi as e:
r = f"❌ {type(e).__name__}: {e}"
print(f" {tavsif:<18} {r}")
print("\n\n7. Qayta urinish:\n")
class NosozYuklovchi(Yuklovchi):
"""Sinov uchun — birinchi 2 urinishda xato."""
def __init__(self, **kw):
super().__init__(**kw)
self._urinish = 0
def _oqi(self, manba):
self._urinish += 1
if self._urinish < 3:
raise VaqtinchalikXato(f"tarmoq xatosi #{self._urinish}")
return super()._oqi(manba)
ny = NosozYuklovchi(urinishlar=5)
n = ny.yukla(CSV_YAXSHI)
print(f" {n}")
print(f" urinishlar: {n.urinishlar}")
ny2 = NosozYuklovchi(urinishlar=2)
try:
ny2.yukla(CSV_YAXSHI)
except VaqtinchalikXato as e:
print(f"\n urinishlar=2 → ❌ {e}")
print("\n\n8. Jurnal:\n")
for q in _bufer.getvalue().rstrip().split("\n")[:10]:
print(f" {q}")
qolgan = len(_bufer.getvalue().rstrip().split("\n")) - 10
if qolgan > 0:
print(f" ... yana {qolgan} qator")
print(f"""
⭐ BU LOYIHADA:
ISTISNO IERARXIYASI:
YuklashXatosi
├── VaqtinchalikXato ⭐ qayta urinish MUMKIN
└── MalumotXatosi ⭐ qayta urinish FOYDASIZ
ANIQ TURLAR:
FileNotFoundError, IsADirectoryError, PermissionError,
UnicodeDecodeError, OSError → MalumotXatosi/VaqtinchalikXato
from e:
Har o'rashda asl sabab saqlanadi
XATOLARNI YIG'ISH:
Bitta yozuv xato → qolganlari yuklanadi
Xato chegarasi va qat'iy rejim
QAYTA URINISH:
Faqat VaqtinchalikXato uchun
Eksponensial kutish
for/else naqshi
JURNAL:
warning — qayta urinish
debug — har xato
⭐ YALANG'OCH except HECH QAYERDA ISHLATILMAGAN
""")Natijaning muhim qismi:
2. ⭐ Qisman muvaffaqiyat (xatolar yig'iladi):
⚠️ qisman: 2 yozuv, 5 xato, 1.2ms
✅ Yuklandi (2):
1. Aziz 8,500,000
7. Jasur 7,500,000
❌ Xatolar (5):
butun son emas: 'xato' (qator 3, ustun 'id')
majburiy maydon yo'q (qator 4, ustun 'ism')
summa emas: "ko'p pul" (qator 5, ustun 'maosh')
⭐ Ish TO'XTAMADI — 5 xatoga qaramay 2 yozuv yuklandi
6. ⭐ Fayl xatolari (aniq turlar):
mavjud fayl ✅ ✅ to'liq: 3 yozuv, 0 xato
mavjud emas ❌ MalumotXatosi: fayl topilmadi
papka ❌ MalumotXatosi: papka, fayl emas
kodlash xatosi ❌ MalumotXatosi: kodlash xatosi (utf-8, bayt 9)
7. Qayta urinish:
✅ to'liq: 3 yozuv, 0 xato, 4.1ms
urinishlar: 3Nima ko'rsatdi: 2.2, 2.3, 2.6, 2.7-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
"except: — qulay qisqartma" |
BaseException — Ctrl+C ni ham ushlaydi |
"except Exception: xavfsiz" |
Keng; faqat yuqori darajada + jurnal bilan |
"except tartibi ahamiyatsiz" |
Avlod avval yozilishi kerak |
"try sekin" |
Istisno bo'lmasa — deyarli bepul |
| "LBYL xavfsizroq" | Poyga holati; EAFP atomik |
"raise e traceback'ni yo'qotadi" |
Python 3 da saqlaydi — faqat ortiqcha yozuv qo'shadi |
"e blokdan keyin ham bor" |
Avtomatik del e |
| "Xato bo'lsa to'xtash kerak" | Ba'zan yig'ib davom etish yaxshiroq |
6. Keng tarqalgan xatolar va yechimlari
1. Yalang'och except:
except: # ❌
except Exception as e: # ⚠️ yuqori darajada
except ValueError as e: # ✅2. Jimgina yutish
except Exception:
pass # ⚠️ xato yo'qoldi
except Exception as e:
jurnal.exception("...") # ✅3. Noto'g'ri tartib
except ValueError: ... # ⚠️ birinchi
except JSONDecodeError: ... # ❌ o'lik kod
# ✅ teskari4. Juda keng try
try:
a = f(); b = g(); c = h() # ⚠️ qaysi biri?
except Exception: ...
# ✅ alohida try yoki aniq turlar5. raise e
except ValueError as e:
raise e # ⚠️ ortiqcha traceback yozuvi
raise # ✅ toza6. e ni tashqarida ishlatish
except ValueError as e: pass
print(e) # ❌ NameError
xato = e # ✅ ichkarida boshqa nomga7. print bilan xato
except Exception as e:
print(f"Xato: {e}") # ⚠️ traceback yo'q
jurnal.exception("Xato") # ✅8. Muqobil borida try
try: return d[k]
except KeyError: return sukut # ⚠️ tez-tez bo'lsa
return d.get(k, sukut) # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 9.1-dars (o'tilgan): traceback va istisno turlari
- 9.3-dars:
elsevafinally - 9.4-9.5: bir nechta istisno,
raise - 9.7: istisnolar ierarxiyasi
- 10-qism: kontekst menejerlari (
with) - 17-qism:
pytest.raises, xatolarni testlash logging,contextlib,retrying/tenacity
8. Eng yaxshi amaliyotlar
Hech qachon
except:yozmang.except Exception:— faqat yuqori darajada.Eng aniq turni ushlang.
FileNotFoundError,ValueErroremas.Avlodni ota-sinfdan oldin.
JSONDecodeError→ValueError.tryblokini qisqa tuting. Faqat xato berishi mumkin bo'lgan qator.Xatoni jurnalga yozing.
logging.exception()—printemas.raiseishlating,raise eemas. Traceback toza bo'lsin.EAFP — sukut tanlov. LBYL — xato tez-tez bo'lsa.
Kontekst qo'shing.
raise UmumiyXato(...) from e.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
1. try:
print("a"); 1/0; print("b")
except ZeroDivisionError: print("c")
print("d")
2. try: 1/0
except ValueError: print("v")
except ZeroDivisionError: print("z")
3. try: 1/0
except Exception: print("e")
except ZeroDivisionError: print("z")
4. try: 1/0
except ZeroDivisionError as e: pass
print(type(e))
5. try:
try: 1/0
except ZeroDivisionError: raise ValueError("v")
except ValueError as e: print(type(e.__context__).__name__)
6. try: raise SystemExit(1)
except Exception: print("ushlandi")
7. try: raise SystemExit(1)
except: print("ushlandi")
8. d = {}
try: d["a"]
except (KeyError, IndexError) as e: print(type(e).__name__)
9. try: raise KeyError("k")
except LookupError as e: print(type(e).__name__, e)
10. def f():
try: return 1
except: return 2
print(f())
11. try:
raise ValueError("a")
except ValueError as e:
e.add_note("izoh")
print(e.__notes__)
12. import json
try: json.loads("{")
except ValueError as e: print(type(e).__name__)Javoblar
a c d—bbajarilmaydize—ZeroDivisionErrorbloki o'lik kodNameError—eo'chirilganZeroDivisionError- Ushlanmaydi — dastur chiqadi (
SystemExit—BaseException) ushlandi— yalang'ochexceptKeyErrorKeyError 'k'—LookupErrorota-sinf1['izoh'](3.11+)JSONDecodeError
Vazifa 2: Xatolarni tuzating
1. try: ish()
except: pass
2. try: ish()
except Exception as e: print(f"Xato: {e}")
3. try:
m = json.loads(s)
except ValueError: ...
except json.JSONDecodeError: ...
4. try:
a = f(); b = g(); c = h()
except Exception: ...
5. except ValueError as e:
tozala()
raise e
6. try: return d[k]
except KeyError: return None
7. while True:
try: ish()
except: continue
8. try: ish()
except Exception as e: xato = e
print(xato)Javoblar
1. except (ValueError, KeyError) as e: jurnal.exception(...)
2. jurnal.exception("Xato") — traceback bilan
3. JSONDecodeError ni AVVAL
4. Har birini alohida try yoki aniq turlar
5. raise (e siz)
6. return d.get(k)
7. except Exception: (KeyboardInterrupt o'tsin)
8. xato = None ni oldindan e'lon qilingVazifa 3: Xavfsiz o'giruvchi
Yozing:
xavfsiz_int(q, sukut=0),xavfsiz_float,xavfsiz_sana- Har biri aniq istisno turlarini ushlasin
- Xato sababini qaytarish imkoniyati
- Ro'yxat uchun ommaviy versiya
- Statistika: muvaffaqiyat/xato
trybloklari minimal bo'lsin
Vazifa 4: except tekshiruvchisi
Vosita yozing (AST bilan):
- Yalang'och
except:larni topsin except Exception: passnaqshini- Noto'g'ri tartibni (ota-sinf avval)
- Juda keng
trybloklarini (>5 qator) raise e(o'rnigaraise)- Muqobil bor joylarda
try(d[k]→d.get)
Vazifa 5: Qayta urinish dekoratori
@qayta_urin(urinishlar=3, kutish=1.0)- Faqat berilgan istisnolarda
- Eksponensial kutish + jitter
- Har urinishni jurnalga
- Yakuniy xato zanjirda asl sababni saqlasin
asyncversiyasi
Vazifa 6: Xatolarni yig'uvchi
- Kontekst menejeri:
with XatoYiguvchi() as y: - Blok ichidagi xatolarni yig'sin
- Chegara: N xatodan keyin ko'tarish
- Guruhlash: tur bo'yicha
- Hisobot: eng ko'p uchraydigan
ExceptionGroupbilan ko'tarish (3.11+)
Vazifa 7: O'ylash
Nega Python except: (yalang'och) sintaksisini taqiqlamadi, agar u shu qadar xavfli bo'lsa?
Javob
Chunki u ba'zan haqiqatan kerak, va Python "kattalar tili" tamoyiliga amal qiladi.
1. Qachon except: haqiqatan kerak
a) Yakuniy tozalash (framework darajasida):
def ishga_tushir():
resurs = ochish()
try:
asosiy_ish()
except: # ⭐ HAMMASI
resurs.yop() # tozalash
raise # ⭐ QAYTA ko'tarish Muhim: raise bilan qayta ko'tariladi. Faqat tozalash uchun.
Lekin finally yaxshiroq:
try:
asosiy_ish()
finally:
resurs.yop() # ✅ soddaroqb) Ipcha ishlovchisi:
def ipcha_ishi():
try:
ish()
except: # ⭐ ipcha O'LMASLIGI kerak
jurnal.exception("Ipchada xato") Ipchada ushlanmagan istisno — ipcha jimgina o'ladi. Lekin except BaseException: ham bir xil.
c) __del__ va tozalash metodlari:
def __del__(self):
try:
self.yop()
except: # ⭐ __del__ da xato yutiladi
pass # baribir ko'rsatilmaydid) Interaktiv REPL, test runner:
while True:
try:
kod = input(">>> ")
exec(kod)
except SystemExit:
raise # ⭐ chiqish ruxsat
except:
traceback.print_exc() # ⭐ boshqa hammasi ko'rsatiladi2. except BaseException: — aniqroq muqobil
except: # ⚠️ niyat noaniq
except BaseException: # ✅ ANIQ — "hammasini bilaman"Ikkalasi texnik jihatdan bir xil, lekin ikkinchisi niyatni bildiradi.
ruff/flake8 E722 qoidasi aynan shuni talab qiladi:
E722 do not use bare 'except'3. Nega taqiqlanmadi
a) Orqaga moslik
except: — Python 1.0 dan beri bor. Uni taqiqlash millionlab qator kodni buzardi.
b) "Consenting adults"
8.10-darsda ko'rgan falsafa: Python dasturchini cheklamaydi, ogohlantiradi.
c) Linterlar hal qiladi
ruff check --select E722 # bare except
pylint --enable=W0702 # bare-except
flake8 # E722Barcha zamonaviy linterlar buni sukut bo'yicha tekshiradi.
d) Ba'zan kerak (yuqoridagi holatlar)
4. Python 3 dagi yaxshilanishlar
Python except: ni taqiqlamadi, lekin uni kamroq kerak qildi:
a) finally (Python 1.5) — tozalash uchun
try:
ish()
finally:
tozala() # ✅ except: kerak emasb) with (Python 2.5, PEP 343) — resurslar uchun
with ochish() as r:
ish() # ✅ avtomatik yopiladic) contextlib.suppress (3.4) — ataylab yutish
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove(yol) # ✅ aniq va qisqa
# o'rniga:
try:
os.remove(yol)
except FileNotFoundError:
passd) missing_ok, exist_ok (3.5-3.8) — tayyor muqobillar
Path(yol).unlink(missing_ok=True) # ✅ try kerak emas
Path(p).mkdir(exist_ok=True)e) ExceptionGroup va except* (3.11) — ko'p istisno
5. Boshqa tillar
| Til | Yalang'och ushlash | Taqiqmi |
|---|---|---|
| Python | except: |
Linter ogohlantiradi |
| Java | catch (Throwable t) |
Ogohlantirish |
| C# | catch { } |
Ogohlantirish |
| JavaScript | catch (e) |
Yagona usul |
| Go | recover() |
Faqat panic |
| Rust | Yo'q | Result<T, E> |
JavaScript eng qiziq:
try {
ish();
} catch (e) { // ⭐ HAR DOIM hammasi
if (e instanceof TypeError) { // ⚠️ qo'lda tekshirish
...
} else {
throw e; // ⚠️ qo'lda qayta ko'tarish
}
}JavaScript da turlar bo'yicha ushlash yo'q — bu Python dan yomonroq.
Rust — butunlay boshqa yondashuv:
match fayl_oqi(yol) {
Ok(matn) => ...,
Err(e) => match e.kind() {
ErrorKind::NotFound => ..., // ⭐ kompilyator BARCHA
ErrorKind::PermissionDenied => ..., // holatlarni talab qiladi
_ => ...,
}
}Rust da istisnolar yo'q — xatolar qiymat sifatida qaytariladi va kompilyator ularni e'tiborsiz qoldirishga yo'l qo'ymaydi.
6. Statistika
GitHub dagi Python kodida (taxminiy):
| Naqsh | Uchrash |
|---|---|
except Exception: |
~45% |
| Aniq tur | ~40% |
except: |
~12% |
except BaseException: |
~3% |
12% — bu millionlab joy. Ko'pchiligi xato.
7. except: ning haqiqiy narxi
# ⚠️ Real hodisa (soddalashtirilgan):
def malumot_yukla():
try:
return baza.sorov("SELECT ...")
except:
return [] # ⚠️ bo'sh ro'yxat
# Nima bo'ldi:
# 1. Baza parol o'zgardi → AuthError
# 2. except: uni yutdi
# 3. Funksiya [] qaytardi
# 4. Hisobot "0 ta yozuv" ko'rsatdi
# 5. ⚠️ Hech kim 3 kun sezmadiEng yomon xato turi: dastur ishlaydi, lekin noto'g'ri.
8. Amaliy qoidalar
# ❌ HECH QACHON
except:
pass
# ⚠️ Faqat qayta ko'tarish bilan
except:
tozala()
raise
# ⚠️ Faqat eng yuqori darajada + jurnal
def main():
try:
ish()
except Exception:
jurnal.exception("Kutilmagan xato")
return 1
return 0
# ✅ Odatiy holat
except (ValueError, KeyError) as e:
jurnal.warning("...", exc_info=e)
# ✅ Ataylab yutish
with contextlib.suppress(FileNotFoundError):
os.remove(yol)9. Linterni sozlash
# pyproject.toml
[tool.ruff.lint]
select = [
"E722", # bare except
"BLE", # blind except (flake8-blind-except)
"TRY", # tryceratops — try/except antipatternlari
]
[tool.ruff.lint.per-file-ignores]
"framework/runner.py" = ["E722"] # ⭐ ataylab10. Xulosa
except: taqiqlanmagan, chunki:
- Ba'zan kerak — framework, ipcha,
__del__ - Orqaga moslik — Python 1.0 dan beri
- "Consenting adults" — cheklash emas, ogohlantirish
- Linterlar hal qiladi —
E722sukut bo'yicha yoqilgan
Lekin Python uni kamroq kerak qildi: finally, with, contextlib.suppress, missing_ok=True, ExceptionGroup.
Amaliy qoida: except: yozayotgan bo'lsangiz — to'xtang va so'rang:
finallyyokiwithyetadimi?contextlib.suppress(AniqTur)yetadimi?except Exception:yetadimi?raisebilan qayta ko'tarayapmanmi?
To'rt savolning hech biriga "yo'q" bo'lsa — ehtimol except: xato.
Nimani mustahkamlaydi: 2.2, 2.7-bo'limlar.
Xulosa
Bu darsda try/except ni o'rgandik.
Eng muhim uch fikr:
Yalang'och
except:—except BaseException:bilan bir xil. UKeyboardInterruptni ushlaydi (Ctrl+Cishlamaydi),SystemExitni to'sadi (dastur to'xtamaydi) va sizning typolaringizni (NameError) jimgina yutadi. Eng aniq turni ushlang;except Exception:— faqat eng yuqori darajada va doim jurnal bilan.excepttartibi muhim: aniqdan umumiyga.JSONDecodeError—ValueErroravlodi, shuning uchun u avval yozilishi kerak; teskari bo'lsa avlod bloki hech qachon ishlamaydi. Bu — jimgina o'lik kod.EAFP — sukut tanlov, lekin mutlaq emas.
try/exceptistisno bo'lmasa deyarli bepul va poyga holatini yo'q qiladi (tekshiruv va amal bitta atomik qadamda). Lekin xato tez-tez bo'lsa (~50%) —ifsezilarli tezroq, vad.get(),next(it, sukut),Path.unlink(missing_ok=True)kabi tayyor muqobillar bor.
Keyingi darsda else va finally bloklarini ko'ramiz: qachon ular kerak, finally va return o'rtasidagi nozik munosabat va resurslarni to'g'ri tozalash.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!