Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Sintaksis va qoidalar
- 2.2. Sukut qiymat QACHON hisoblanadi
- 2.3. Mashhur tuzoq
- 2.4. Yechimlar
- 2.5. Qachon o'zgaruvchan sukut FOYDALI
- 2.6. __defaults__ va __kwdefaults__
- 2.7. Sukut qiymatlar dizayni
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Tuzoq va uning mexanizmi
- Misol 2 — Sentinel va nozik holatlar
- Misol 3 — Qachon o'zgaruvchan sukut foydali
- Misol 4 — Amaliy: konfiguratsiya funksiyalari
- 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
7.3-dars: Standart qiymatlar va mashhur tuzoq
7-QISM — FUNKSIYALAR · 3-dars
1. Kirish va motivatsiya
Standart (sukut) qiymat funksiyani qulayroq qiladi:
def salomlash(ism, salom="Salom"):
return f"{salom}, {ism}!"
salomlash("Aziz") # "Salom, Aziz!"
salomlash("Aziz", "Assalomu alaykum") # "Assalomu alaykum, Aziz!"Lekin bitta xato butun Python jamoasiga tanish:
def qosh(element, royxat=[]):
royxat.append(element)
return royxat
print(qosh(1)) # [1]
print(qosh(2)) # [1, 2] ⚠️ nega?!
print(qosh(3)) # [1, 2, 3] ⚠️Har chaqiruvda yangi bo'sh ro'yxat kutilardi. Lekin bitta ro'yxat qayta ishlatilyapti.
Bu — Pythonning eng mashhur tuzog'i. Va u faqat ro'yxat bilan emas:
def f(d={}): ... # ⚠️
def f(s=set()): ... # ⚠️
def f(v=datetime.now()): ... # ⚠️ vaqt QOTIB QOLADI
def f(x=[], y=x): ... # ⚠️Bu darsda:
- Sukut qiymatlar sintaksisi va qoidalari
- Mashhur tuzoq — nega shunday va qanday hal qilish
Nonenaqshi va uning variantlari- Sentinel qiymatlar
- Sukut qiymat qachon hisoblanadi
__defaults__va__kwdefaults__
2. Nazariya — chuqur tushuntirish
2.1. Sintaksis va qoidalar
def f(a, b=2, c=3):
return a, b, c
f(1) # (1, 2, 3)
f(1, 20) # (1, 20, 3)
f(1, 20, 30) # (1, 20, 30)
f(1, c=30) # (1, 2, 30)Sukut qiymatli parametrlar OXIRIDA:
def f(a=1, b): ... # ❌ SyntaxError: non-default argument follows default argument
def f(a, b=1): ... # ✅Sabab: aks holda f(5) da 5 qaysi parametrga tegishli ekani noaniq bo'lardi.
* dan keyin cheklov yo'q (6-dars):
def f(a, *, b, c=1): ... # ✅ b majburiy, c sukut bilanSukut qiymat sifatida nima bo'lishi mumkin:
def f(a=1): ... # son
def f(a="x"): ... # satr
def f(a=None): ... # None
def f(a=()): ... # bo'sh tuple
def f(a=frozenset()): ... # frozenset
def f(a=CONSTANT): ... # modul konstantasi
def f(a=hisobla()): ... # ⚠️ funksiya chaqiruvi — ehtiyot bo'ling
def f(a=[]): ... # ⚠️ o'zgaruvchan — TUZOQ2.2. Sukut qiymat QACHON hisoblanadi
Javob: funksiya ANIQLANGANDA, bir marta.
def f(x=hisobla()):
return xhisobla() — def qatori bajarilganda bir marta chaqiriladi. Chaqiruvlarda emas.
Namoyish:
chaqiruvlar = []
def qimmat():
chaqiruvlar.append(1)
return len(chaqiruvlar)
def f(x=qimmat()):
return x
print(chaqiruvlar) # [1] ← def bajarilganda chaqirilgan
f(); f(); f()
print(chaqiruvlar) # [1] ← ko'proq chaqirilmadiBu — vaqt bilan bog'liq tuzoq:
from datetime import datetime
def yozuv(matn, vaqt=datetime.now()): # ⚠️
return f"[{vaqt}] {matn}"
yozuv("birinchi") # [2026-09-08 10:00:00] birinchi
# ... 3 soatdan keyin
yozuv("ikkinchi") # [2026-09-08 10:00:00] ikkinchi ⚠️ ESKI VAQTYechim:
def yozuv(matn, vaqt=None):
if vaqt is None:
vaqt = datetime.now() # ✅ har chaqiruvda
return f"[{vaqt}] {matn}"Sukut qiymat funksiya obyektida saqlanadi:
def f(a=1, b=[]): ...
f.__defaults__ # (1, [])Bu — bitta obyekt. Har chaqiruvda o'sha obyekt ishlatiladi.
Sukut qiymatni ishlash vaqtida o'zgartirish:
def f(a=1): return a
f() # 1
f.__defaults__ = (99,)
f() # 99 ⚠️ ishlaydi, lekin qilmang2.3. Mashhur tuzoq
def qosh(element, royxat=[]):
royxat.append(element)
return royxatNima sodir bo'ladi:
defbajarilganda[]bir marta yaratiladi- U
qosh.__defaults__da saqlanadi - Har chaqiruvda (
royxatberilmasa) o'sha ro'yxat ishlatiladi appenduni o'zgartiradi- Keyingi chaqiruv o'zgargan ro'yxatni ko'radi
qosh(1) # [1]
qosh.__defaults__ # ([1],) ← sukut qiymat O'ZGARDI!
qosh(2) # [1, 2]
qosh.__defaults__ # ([1, 2],)Barcha o'zgaruvchan turlar uchun:
def f(d={}): ... # dict
def f(s=set()): ... # set
def f(b=bytearray()): ...
def f(o=MeningSinf()): ... # o'zgaruvchan obyektO'zgarmas turlar xavfsiz:
def f(a=1): ... # int
def f(s="x"): ... # str
def f(t=()): ... # tuple
def f(f=frozenset()): ...
def f(n=None): ... # NoneLekin tuple ichida o'zgaruvchan bo'lsa:
def f(t=(1, [])): # ⚠️ ichidagi ro'yxat umumiy
t[1].append(1)2.4. Yechimlar
1. None naqshi (standart):
def qosh(element, royxat=None):
if royxat is None:
royxat = []
royxat.append(element)
return royxat if royxat is None, if not royxat emas:
def f(r=None):
if not r: # ⚠️ bo'sh ro'yxat ham None kabi qaraladi
r = [0]
f([]) # [0] ⚠️ foydalanuvchi bo'sh ro'yxat berdi!is None — aniq va to'g'ri.
Qisqa shakl:
def f(r=None):
r = [] if r is None else r # ✅
r = r if r is not None else [] # ✅
r = r or [] # ⚠️ bo'sh ro'yxat almashtiriladi2. O'zgarmas sukut:
def qosh(element, royxat=()):
return [*royxat, element] # ✅ yangi ro'yxatBu — argumentni ham o'zgartirmaydi (7.2-dars).
3. Ichkarida nusxa:
def qayta_ishla(r=None):
r = list(r or []) # ✅ nusxa
r.sort()
return r4. Sentinel obyekt (None ham yaroqli qiymat bo'lsa):
YOQ = object()
def f(x=YOQ):
if x is YOQ:
x = hisobla_sukut()
...
f() # sukut hisoblanadi
f(None) # ⭐ None ham yaroqli qiymat sifatida uzatiladiAmaliy misol:
def d_ol(d, kalit, sukut=YOQ):
"""None ni ham yaroqli qiymat sifatida qaytaradi."""
if kalit in d:
return d[kalit]
if sukut is YOQ:
raise KeyError(kalit)
return sukutSentinel uchun variantlar:
YOQ = object() # ✅ oddiy
_YOQ = object() # ✅ modul ichida
class _Yoq: # ✅ repr yaxshiroq
def __repr__(self): return "<YOQ>"
YOQ = _Yoq()
from enum import Enum # ✅ eng aniq
class _Sentinel(Enum):
YOQ = object()
YOQ = _Sentinel.YOQ5. Dekorator bilan (kam ishlatiladi):
def yangi_sukut(**sukutlar):
def dekorator(f):
@wraps(f)
def ichki(*args, **kwargs):
for nom, yaratuvchi in sukutlar.items():
kwargs.setdefault(nom, yaratuvchi())
return f(*args, **kwargs)
return ichki
return dekorator
@yangi_sukut(royxat=list)
def qosh(element, royxat):
royxat.append(element)
return royxat2.5. Qachon o'zgaruvchan sukut FOYDALI
Tuzoq — ba'zan xususiyat:
1. Kesh (memoizatsiya):
def fib(n, kesh={0: 0, 1: 1}):
if n not in kesh:
kesh[n] = fib(n - 1, kesh) + fib(n - 2, kesh)
return kesh[n]
fib(100) # tez — kesh saqlanadi Lekin functools.lru_cache aniqroq:
@lru_cache(maxsize=None)
def fib(n):
return n if n < 2 else fib(n - 1) + fib(n - 2)2. Chaqiruvlarni sanash:
def f(hisob=[0]):
hisob[0] += 1
return hisob[0]Funksiya atributi aniqroq:
def f():
f.hisob += 1
return f.hisob
f.hisob = 03. Tezlik uchun oldindan hisoblash:
def tozala(matn, jadval=str.maketrans("", "", ".,!?")):
return matn.translate(jadval) # ⚠️ jadval bir marta yaratiladiModul konstantasi aniqroq:
JADVAL = str.maketrans("", "", ".,!?")
def tozala(matn):
return matn.translate(JADVAL)4. Lokal nomni tezlashtirish (mikro-optimallashtirish):
def f(r, _len=len, _range=range): # ⚠️ eski hiyla
for i in _range(_len(r)): ...Bu — global qidiruvni lokalga aylantiradi. Zamonaviy Pythonda foyda kichik va kod o'qilishi yomonlashadi.
Xulosa: o'zgaruvchan sukut qiymat ataylab ishlatilishi mumkin, lekin deyarli har doim aniqroq muqobil bor.
2.6. __defaults__ va __kwdefaults__
def f(a, b=2, c=3, *, d=4, e=5):
...
f.__defaults__ # (2, 3) — pozitsion parametrlar sukuti
f.__kwdefaults__ # {'d': 4, 'e': 5} — faqat nomli __defaults__ — oxiridan bog'lanadi:
def f(a, b, c=3):
...
f.__defaults__ # (3,) ← faqat cnamedtuple(defaults=...) bilan bir xil mantiq (6.6-dars).
inspect bilan aniqroq:
import inspect
sig = inspect.signature(f)
for nom, p in sig.parameters.items():
print(nom, p.default, p.kind)a <class 'inspect._empty'> POSITIONAL_OR_KEYWORD
b 2 POSITIONAL_OR_KEYWORD
c 3 POSITIONAL_OR_KEYWORD
d 4 KEYWORD_ONLYSukut qiymatlarni tekshirish vositasi:
def ozgaruvchan_sukutlarni_top(f):
"""O'zgaruvchan sukut qiymatlarni topadi."""
OZGARUVCHAN = (list, dict, set, bytearray)
natija = []
for nom, p in inspect.signature(f).parameters.items():
if p.default is not inspect.Parameter.empty:
if isinstance(p.default, OZGARUVCHAN):
natija.append((nom, p.default))
return natijaLinterlar (ruff, pylint, flake8-bugbear) buni avtomatik topadi:
B006 Do not use mutable data structures for argument defaults2.7. Sukut qiymatlar dizayni
1. Sukut qiymat — eng ko'p ishlatiladigan holat:
def ochish(yol, rejim="r", kodlash="utf-8"): ... # ✅
def ochish(yol, rejim, kodlash): ... # ⚠️ har safar yozish kerak2. Sukut qiymat xavfsiz bo'lsin:
def ochish(yol, rejim="w"): ... # ⚠️ tasodifan yozib yuborish
def ochish(yol, rejim="r"): ... # ✅ o'qish xavfsizroq3. Sukut qiymat oldindan aytiladigan bo'lsin:
def sarala(r, kamayish=False): ... # ✅ tabiiy
def sarala(r, kamayish=True): ... # ⚠️ kutilmagan4. None — "ko'rsatilmagan" ma'nosida:
def qidir(matn, chegara=None):
"""chegara=None — cheklov yo'q."""
...5. Bir-biriga bog'liq sukutlar:
def yarat(kenglik=None, balandlik=None):
if kenglik is None and balandlik is None:
kenglik, balandlik = 80, 24
elif kenglik is None:
kenglik = balandlik * 3
elif balandlik is None:
balandlik = kenglik // 3
...Sukut qiymat boshqa parametrga tayana olmaydi:
def f(a, b=a): ... # ❌ NameError: name 'a' is not defined
def f(a, b=None): # ✅
b = a if b is None else b3. Tez ma'lumotnoma
Sintaksis
def f(a, b=2, c=3): ... sukutlar OXIRIDA
def f(a=1, b): ... ❌ SyntaxError
def f(a, *, b, c=1): ... ✅ * dan keyin cheklov yo'q
def f(a, b=a): ... ❌ boshqa parametrga tayanolmaydiSukut qiymat DEF paytida bir marta hisoblanadi
def f(x=qimmat()): ... qimmat() BIR MARTA — def qatorida
def f(v=datetime.now()): ... ⚠️ vaqt QOTIB QOLADI
f.__defaults__ saqlangan obyektlarMASHHUR TUZOQ
def f(r=[]): ❌ BITTA ro'yxat barcha chaqiruvga
r.append(1); return r
f() → [1]; f() → [1,1]; f() → [1,1,1]
✅ Yechimlar:
def f(r=None): r = [] if r is None else r
def f(r=()): return [*r, x]
def f(r=None): r = list(r or [])
YOQ = object(); def f(x=YOQ): ... (None ham yaroqli bo'lsa) is None, not r emas
if r is None: r = [] ✅
if not r: r = [] ⚠️ bo'sh ro'yxat ham almashtiriladi
r = r or [] ⚠️ bir xil muammoXavfsiz sukut turlari
✅ int, float, str, bool, None, tuple, frozenset, bytes
⚠️ list, dict, set, bytearray, o'zgaruvchan obyektlar
⚠️ (1, []) — tuple ichida o'zgaruvchanTekshirish
f.__defaults__ pozitsion sukutlar (OXIRIDAN)
f.__kwdefaults__ faqat nomli sukutlar
inspect.signature(f) to'liq
ruff / pylint: B006 avtomatik topadi4. Batafsil misollar
Misol 1 — Tuzoq va uning mexanizmi
"""Mashhur tuzoq — nima uchun va qanday hal qilish."""
print("=== 1. ⭐ Tuzoq ===")
def qosh_yomon(element, royxat=[]):
royxat.append(element)
return royxat
print(f" def qosh(element, royxat=[]):\n")
for i in range(1, 5):
print(f" qosh({i}) → {qosh_yomon(i)}")
print(f"\n ⚠️ Har chaqiruvda yangi ro'yxat KUTILARDI, lekin bitta ishlatildi")
print("\n=== 2. Sabab: __defaults__ ===")
def qosh(element, royxat=[]):
royxat.append(element)
return royxat
print(f" Boshida:")
print(f" qosh.__defaults__ = {qosh.__defaults__}")
print(f" id(qosh.__defaults__[0]) = {id(qosh.__defaults__[0])}\n")
for i in range(1, 4):
natija = qosh(i)
print(f" qosh({i}) → {natija}")
print(f" __defaults__ = {qosh.__defaults__}")
print(f" natija is __defaults__[0]: {natija is qosh.__defaults__[0]}")
print("""
⭐ Sukut qiymat funksiya OBYEKTIDA saqlanadi.
Har chaqiruvda O'SHA obyekt ishlatiladi.
append uni o'zgartiradi.
""")
print("\n=== 3. Sukut qiymat QACHON hisoblanadi ===")
chaqiruvlar = []
def qimmat():
chaqiruvlar.append(len(chaqiruvlar) + 1)
print(f" qimmat() chaqirildi (#{len(chaqiruvlar)})")
return len(chaqiruvlar)
print(f" def f(x=qimmat()):")
def f(x=qimmat()):
return x
print(f" ↑ def bajarilganda chaqirildi\n")
print(f" Chaqiruvlar:")
for _ in range(3):
print(f" f() → {f()}")
print(f"\n qimmat() jami chaqirilishi: {len(chaqiruvlar)}")
print(f" ⭐ BIR MARTA — def qatorida")
print("\n=== 4. ⚠️ Vaqt tuzog'i ===")
from datetime import datetime
import time
def yozuv_yomon(matn, vaqt=datetime.now()):
return f"[{vaqt:%H:%M:%S.%f}] {matn}"
def yozuv_yaxshi(matn, vaqt=None):
vaqt = vaqt or datetime.now()
return f"[{vaqt:%H:%M:%S.%f}] {matn}"
print(f" ❌ vaqt=datetime.now():")
for i in range(3):
print(f" {yozuv_yomon(f'xabar {i}')}")
time.sleep(0.05)
print(f"\n ✅ vaqt=None + ichkarida:")
for i in range(3):
print(f" {yozuv_yaxshi(f'xabar {i}')}")
time.sleep(0.05)
print("\n=== 5. Barcha o'zgaruvchan turlar ===")
def f_list(x, r=[]):
r.append(x); return r
def f_dict(x, d={}):
d[x] = x * 2; return d
def f_set(x, s=set()):
s.add(x); return s
def f_bytearray(x, b=bytearray()):
b.append(x); return b
TURLAR = [
("list", f_list, [1, 2, 3]),
("dict", f_dict, [1, 2, 3]),
("set", f_set, [1, 2, 3]),
("bytearray", f_bytearray, [65, 66, 67]),
]
print(f" {'Tur':<12} {'1-chaqiruv':<18} {'2-chaqiruv':<22} {'3-chaqiruv'}")
print(" " + "─" * 72)
for nom, f, args in TURLAR:
natijalar = [str(f(a)) for a in args]
print(f" {nom:<12} {natijalar[0]:<18} {natijalar[1]:<22} {natijalar[2]}")
print(f"\n ✅ O'zgarmas turlar xavfsiz:")
def f_int(x, n=0):
n += x; return n
def f_str(x, s=""):
s += str(x); return s
def f_tuple(x, t=()):
t = t + (x,); return t
for nom, f in [("int", f_int), ("str", f_str), ("tuple", f_tuple)]:
natijalar = [str(f(i)) for i in [1, 2, 3]]
print(f" {nom:<8} {' → '.join(natijalar)}")
print(f"\n ⚠️ Tuple ICHIDA o'zgaruvchan:")
def f_tuple_ichida(x, t=(1, [])):
t[1].append(x)
return t
for i in [1, 2, 3]:
print(f" f({i}) → {f_tuple_ichida(i)}")
print("\n=== 6. Yechimlar ===")
def y1(element, royxat=None):
"""None naqshi (standart)."""
if royxat is None:
royxat = []
royxat.append(element)
return royxat
def y2(element, royxat=()):
"""O'zgarmas sukut."""
return [*royxat, element]
def y3(element, royxat=None):
"""Ichkarida nusxa."""
royxat = list(royxat or [])
royxat.append(element)
return royxat
YOQ = object()
def y4(element, royxat=YOQ):
"""Sentinel — None ham yaroqli qiymat bo'lsa."""
if royxat is YOQ:
royxat = []
elif royxat is None:
royxat = ["(None berildi)"]
else:
royxat = list(royxat)
royxat.append(element)
return royxat
YECHIMLAR = [
("y1: None naqshi", y1),
("y2: () sukut", y2),
("y3: nusxa", y3),
("y4: sentinel", y4),
]
print(f" {'Yechim':<22} {'f(1)':<12} {'f(2)':<12} {'f(3)'}")
print(" " + "─" * 58)
for nom, f in YECHIMLAR:
natijalar = [str(f(i)) for i in [1, 2, 3]]
print(f" {nom:<22} {natijalar[0]:<12} {natijalar[1]:<12} {natijalar[2]}")
print(f"\n Sentinel — None bilan farq:")
print(f" y4(1) → {y4(1)}")
print(f" y4(1, None) → {y4(1, None)} ⭐ None ham qabul qilinadi")
print("\n=== 7. ⚠️ is None vs not r ===")
def yomon_tekshiruv(r=None):
if not r: # ⚠️
r = ["sukut"]
return r
def yaxshi_tekshiruv(r=None):
if r is None: # ✅
r = ["sukut"]
return r
SINOVLAR = [None, [], [1, 2], 0, "", {}]
print(f" {'Kirish':<12} {'not r bilan':<24} {'is None bilan'}")
print(" " + "─" * 60)
for kirish in SINOVLAR:
a = yomon_tekshiruv(kirish)
b = yaxshi_tekshiruv(kirish)
belgi = "⚠️" if a != b else " "
print(f" {str(kirish):<12} {str(a):<24} {belgi} {b}")
print("""
⚠️ `not r` bo'sh ro'yxat, 0, "" ni ham None kabi qaraydi.
Foydalanuvchi ATAYLAB bo'sh ro'yxat bergan bo'lishi mumkin.
✅ `is None` — aniq va to'g'ri.
""")Natijaning muhim qismi:
=== 1. ⭐ Tuzoq ===
def qosh(element, royxat=[]):
qosh(1) → [1]
qosh(2) → [1, 2]
qosh(3) → [1, 2, 3]
qosh(4) → [1, 2, 3, 4]
=== 2. Sabab: __defaults__ ===
qosh(1) → [1]
__defaults__ = ([1],)
natija is __defaults__[0]: True
=== 5. Barcha o'zgaruvchan turlar ===
Tur 1-chaqiruv 2-chaqiruv 3-chaqiruv
────────────────────────────────────────────────────────────────────────
list [1] [1, 2] [1, 2, 3]
dict {1: 2} {1: 2, 2: 4} {1: 2, 2: 4, 3: 6}
set {1} {1, 2} {1, 2, 3}
=== 7. ⚠️ is None vs not r ===
Kirish not r bilan is None bilan
────────────────────────────────────────────────────────────
None ['sukut'] ['sukut']
[] ['sukut'] ⚠️ []
0 ['sukut'] ⚠️ 0Nima ko'rsatdi: 2.2, 2.3, 2.4-bo'limlar.
Misol 2 — Sentinel va nozik holatlar
"""None ham yaroqli qiymat bo'lganda."""
from enum import Enum
print("=== 1. Muammo: None yaroqli qiymat ===")
def sozla_yomon(kalit, qiymat=None):
"""⚠️ None ni 'ko'rsatilmagan' deb qaraydi."""
if qiymat is None:
qiymat = "SUKUT"
return {kalit: qiymat}
print(f" def sozla(kalit, qiymat=None):\n")
print(f" sozla('a') → {sozla_yomon('a')}")
print(f" sozla('a', 1) → {sozla_yomon('a', 1)}")
print(f" sozla('a', None) → {sozla_yomon('a', None)} "
f"⚠️ None ni ataylab bermoqchi edik!")
print("\n=== 2. Sentinel yechimi ===")
YOQ = object()
def sozla_yaxshi(kalit, qiymat=YOQ):
"""✅ None ham yaroqli qiymat."""
if qiymat is YOQ:
qiymat = "SUKUT"
return {kalit: qiymat}
print(f" YOQ = object()")
print(f" def sozla(kalit, qiymat=YOQ):\n")
print(f" sozla('a') → {sozla_yaxshi('a')}")
print(f" sozla('a', 1) → {sozla_yaxshi('a', 1)}")
print(f" sozla('a', None) → {sozla_yaxshi('a', None)} ✅")
print("\n=== 3. Sentinel variantlari ===")
# 1. Oddiy object
YOQ1 = object()
# 2. repr bilan
class _Yoq:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __repr__(self):
return "<YOQ>"
def __bool__(self):
return False
YOQ2 = _Yoq()
# 3. Enum bilan (eng aniq)
class _Sentinel(Enum):
YOQ = "yoq"
def __repr__(self):
return "<YOQ>"
YOQ3 = _Sentinel.YOQ
# 4. Maxsus sinf
class YOQTuri:
__slots__ = ()
def __repr__(self):
return "YOQ"
YOQ4 = YOQTuri()
VARIANTLAR = [
("object()", YOQ1),
("Singleton sinf", YOQ2),
("Enum", YOQ3),
("__slots__ sinf", YOQ4),
]
print(f" {'Variant':<20} {'repr':<20} {'bool':<8} {'Xotira'}")
print(" " + "─" * 58)
import sys
for nom, s in VARIANTLAR:
print(f" {nom:<20} {repr(s):<20} {str(bool(s)):<8} {sys.getsizeof(s)} B")
print("""
⭐ Tavsiya:
• Modul ichida: _YOQ = object()
• Ochiq API da: Enum yoki maxsus sinf (repr yaxshiroq)
• Python 3.12+: typing.Sentinel (PEP 661 — hali qabul qilinmagan)
""")
print("\n=== 4. Amaliy: xavfsiz dict.get ===")
YOQ = object()
def ol(d: dict, kalit, sukut=YOQ):
"""dict.get ga o'xshash, lekin None ni farqlaydi."""
if kalit in d:
return d[kalit]
if sukut is YOQ:
raise KeyError(kalit)
return sukut
D = {"a": 1, "b": None, "yoq": 0}
SINOVLAR = [
("ol(d, 'a')", lambda: ol(D, "a")),
("ol(d, 'b')", lambda: ol(D, "b")),
("ol(d, 'z')", lambda: ol(D, "z")),
("ol(d, 'z', None)", lambda: ol(D, "z", None)),
("ol(d, 'z', 'sukut')", lambda: ol(D, "z", "sukut")),
("d.get('b')", lambda: D.get("b")),
("d.get('z')", lambda: D.get("z")),
]
print(f" d = {D}\n")
print(f" {'Chaqiruv':<24} {'Natija'}")
print(" " + "─" * 48)
for kod, f in SINOVLAR:
try:
natija = repr(f())
except KeyError as x:
natija = f"❌ KeyError: {x}"
print(f" {kod:<24} {natija}")
print("""
⚠️ d.get('b') va d.get('z') ikkalasi ham None —
kalit yo'qmi yoki qiymati None mi, farqlab bo'lmaydi.
⭐ Sentinel bilan farq aniq.
""")
print("\n=== 5. Bir-biriga bog'liq sukutlar ===")
print(f" ❌ Boshqa parametrga tayanish mumkin emas:")
print(f" def f(a, b=a): ... → NameError\n")
def olcham_yaxshi(kenglik=None, balandlik=None, nisbat=3):
"""✅ None + mantiq ichkarida."""
if kenglik is None and balandlik is None:
kenglik, balandlik = 80, 80 // nisbat
elif kenglik is None:
kenglik = balandlik * nisbat
elif balandlik is None:
balandlik = max(1, kenglik // nisbat)
return kenglik, balandlik
SINOVLAR = [
({}, "ikkalasi ham sukut"),
({"kenglik": 120}, "faqat kenglik"),
({"balandlik": 40}, "faqat balandlik"),
({"kenglik": 100, "balandlik": 50}, "ikkalasi"),
({"kenglik": 120, "nisbat": 4}, "nisbat bilan"),
]
print(f" {'Argumentlar':<34} {'Natija':<14} Izoh")
print(" " + "─" * 66)
for kwargs, izoh in SINOVLAR:
natija = olcham_yaxshi(**kwargs)
print(f" {str(kwargs):<34} {str(natija):<14} {izoh}")
print("\n=== 6. Sukut qiymatlarni tekshirish ===")
import inspect
def ozgaruvchan_sukutlarni_top(f):
"""O'zgaruvchan sukut qiymatlarni topadi."""
OZGARUVCHAN = (list, dict, set, bytearray)
natija = []
try:
sig = inspect.signature(f)
except (ValueError, TypeError):
return natija
for nom, p in sig.parameters.items():
if p.default is inspect.Parameter.empty:
continue
if isinstance(p.default, OZGARUVCHAN):
natija.append((nom, type(p.default).__name__, p.default))
elif isinstance(p.default, tuple):
for i, el in enumerate(p.default):
if isinstance(el, OZGARUVCHAN):
natija.append((f"{nom}[{i}]", type(el).__name__, el))
return natija
def yomon1(a, r=[]): ...
def yomon2(a, d={}, s=set()): ...
def yomon3(a, t=(1, [])): ...
def yaxshi1(a, r=None): ...
def yaxshi2(a, t=(), f=frozenset()): ...
def yaxshi3(a=1, b="x", c=None): ...
FUNKSIYALAR = [yomon1, yomon2, yomon3, yaxshi1, yaxshi2, yaxshi3]
print(f" {'Funksiya':<12} {'Muammolar'}")
print(" " + "─" * 56)
for f in FUNKSIYALAR:
muammolar = ozgaruvchan_sukutlarni_top(f)
if muammolar:
matn = ", ".join(f"{n}={t}" for n, t, _ in muammolar)
print(f" {f.__name__:<12} ⚠️ {matn}")
else:
print(f" {f.__name__:<12} ✅ toza")
print("""
⭐ Linterlar buni avtomatik topadi:
ruff: B006
flake8-bugbear: B006
pylint: W0102 (dangerous-default-value)
""")
print("\n=== 7. __defaults__ va __kwdefaults__ ===")
def toliq(a, b, c=3, d=4, *args, e=5, f=6, **kwargs):
...
print(f" def toliq(a, b, c=3, d=4, *args, e=5, f=6, **kwargs):\n")
print(f" __defaults__ = {toliq.__defaults__}")
print(f" __kwdefaults__ = {toliq.__kwdefaults__}")
print(f"\n ⭐ __defaults__ OXIRIDAN bog'lanadi:")
print(f" (3, 4) → c=3, d=4 (a va b sukutsiz)\n")
print(f" inspect bilan to'liq:")
print(f" {'Parametr':<10} {'Sukut':<12} {'Tur'}")
print(" " + "─" * 48)
for nom, p in inspect.signature(toliq).parameters.items():
sukut = "—" if p.default is inspect.Parameter.empty else repr(p.default)
print(f" {nom:<10} {sukut:<12} {p.kind.name}")
print(f"\n ⚠️ Sukutni ish vaqtida o'zgartirish:")
def g(x=1):
return x
print(f" g() = {g()}")
g.__defaults__ = (99,)
print(f" g.__defaults__ = (99,)")
print(f" g() = {g()} ⚠️ ishlaydi, lekin QILMANG")Natijaning muhim qismi:
=== 2. Sentinel yechimi ===
sozla('a') → {'a': 'SUKUT'}
sozla('a', 1) → {'a': 1}
sozla('a', None) → {'a': None} ✅
=== 4. Amaliy: xavfsiz dict.get ===
Chaqiruv Natija
────────────────────────────────────────────────
ol(d, 'a') 1
ol(d, 'b') None
ol(d, 'z') ❌ KeyError: 'z'
ol(d, 'z', None) None
d.get('b') None
d.get('z') None
=== 6. Sukut qiymatlarni tekshirish ===
Funksiya Muammolar
────────────────────────────────────────────────────────
yomon1 ⚠️ r=list
yomon2 ⚠️ d=dict, s=set
yomon3 ⚠️ t[1]=list
yaxshi1 ✅ tozaNima ko'rsatdi: 2.4, 2.6, 2.7-bo'limlar.
Misol 3 — Qachon o'zgaruvchan sukut foydali
"""Tuzoq — ba'zan xususiyat."""
import time
from functools import lru_cache
print("=== 1. Kesh (memoizatsiya) ===")
def fib_kesh(n, kesh={0: 0, 1: 1}):
"""⚠️ O'zgaruvchan sukut — ATAYLAB kesh sifatida."""
if n not in kesh:
kesh[n] = fib_kesh(n - 1, kesh) + fib_kesh(n - 2, kesh)
return kesh[n]
def fib_sekin(n):
"""Keshsiz — eksponensial."""
return n if n < 2 else fib_sekin(n - 1) + fib_sekin(n - 2)
@lru_cache(maxsize=None)
def fib_lru(n):
"""✅ Standart usul."""
return n if n < 2 else fib_lru(n - 1) + fib_lru(n - 2)
N = 30
boshlandi = time.perf_counter()
n1 = fib_sekin(N)
vaqt_sekin = time.perf_counter() - boshlandi
boshlandi = time.perf_counter()
n2 = fib_kesh(N)
vaqt_kesh = time.perf_counter() - boshlandi
boshlandi = time.perf_counter()
n3 = fib_lru(N)
vaqt_lru = time.perf_counter() - boshlandi
assert n1 == n2 == n3
print(f" fib({N}) = {n1:,}\n")
print(f" {'Usul':<26} {'Vaqt':>12}")
print(" " + "─" * 40)
print(f" {'Keshsiz (rekursiv)':<26} {vaqt_sekin * 1000:>9.2f} ms")
print(f" {'O`zgaruvchan sukut':<26} {vaqt_kesh * 1000:>9.4f} ms")
print(f" {'@lru_cache':<26} {vaqt_lru * 1000:>9.4f} ms")
print(f"\n Kesh holati:")
print(f" fib_kesh.__defaults__[0] — {len(fib_kesh.__defaults__[0])} yozuv")
print(f" fib_lru.cache_info() — {fib_lru.cache_info()}")
print("""
⚠️ Ikkalasi ham ishlaydi, LEKIN:
• O'zgaruvchan sukut — niyat yashirin, kesh tozalanmaydi
• @lru_cache — aniq, maxsize bor, cache_clear() bor
""")
print(f" @lru_cache imkoniyatlari:")
print(f" fib_lru.cache_clear() — tozalash")
print(f" fib_lru.cache_info() — statistika")
print(f" maxsize=128 — chegara (LRU)")
print("\n=== 2. Chaqiruvlarni sanash ===")
def sana_sukut(hisob=[0]):
"""⚠️ Ro'yxat ichida hisoblagich."""
hisob[0] += 1
return hisob[0]
def sana_atribut():
"""✅ Funksiya atributi — aniqroq."""
sana_atribut.hisob += 1
return sana_atribut.hisob
sana_atribut.hisob = 0
class Sanagich:
"""✅ Sinf — eng aniq."""
def __init__(self):
self.hisob = 0
def __call__(self):
self.hisob += 1
return self.hisob
sana_sinf = Sanagich()
USULLAR = [
("Sukut ro'yxat", sana_sukut),
("Funksiya atributi", sana_atribut),
("Sinf (__call__)", sana_sinf),
]
print(f" {'Usul':<22} {'1':>4} {'2':>4} {'3':>4} Holatga kirish")
print(" " + "─" * 60)
for nom, f in USULLAR:
natijalar = [f() for _ in range(3)]
if nom == "Sukut ro'yxat":
kirish = "f.__defaults__[0][0]"
elif nom == "Funksiya atributi":
kirish = "f.hisob"
else:
kirish = "f.hisob"
print(f" {nom:<22} {natijalar[0]:>4} {natijalar[1]:>4} "
f"{natijalar[2]:>4} {kirish}")
print("""
⭐ Ikkalasi ishlaydi, lekin funksiya atributi va sinf
NIYATNI ochiq ko'rsatadi.
""")
print("\n=== 3. Oldindan hisoblash ===")
def tozala_sukut(matn, jadval=str.maketrans("", "", ".,!?;:")):
"""⚠️ Jadval bir marta yaratiladi (sukut sifatida)."""
return matn.translate(jadval)
JADVAL = str.maketrans("", "", ".,!?;:")
def tozala_konstanta(matn):
"""✅ Modul konstantasi — aniqroq."""
return matn.translate(JADVAL)
def tozala_ichkarida(matn):
"""❌ Har chaqiruvda yangi jadval."""
return matn.translate(str.maketrans("", "", ".,!?;:"))
MATN = "Salom, dunyo! Qalaysiz?" * 10
import timeit
SOZLASH = "from __main__ import tozala_sukut, tozala_konstanta, tozala_ichkarida, MATN"
print(f" {'Usul':<26} {'Vaqt':>12}")
print(" " + "─" * 42)
for nom, kod in [
("Sukut argument", "tozala_sukut(MATN)"),
("Modul konstantasi", "tozala_konstanta(MATN)"),
("Har chaqiruvda", "tozala_ichkarida(MATN)"),
]:
vaqt = timeit.timeit(kod, setup=SOZLASH, number=50_000)
print(f" {nom:<26} {vaqt:>9.3f} s")
print("""
⭐ Sukut va konstanta bir xil tez.
Konstanta — o'qilishi yaxshiroq va tasodifan
o'zgartirib bo'lmaydi (sukut argumentni o'zgartirish mumkin).
""")
print("\n=== 4. Lokal nom optimallashtirishi ===")
def yigindi_oddiy(r):
natija = 0
for x in r:
natija += len(str(x))
return natija
def yigindi_lokal(r, _len=len, _str=str):
"""⚠️ Eski mikro-optimallashtirish hiylasi."""
natija = 0
for x in r:
natija += _len(_str(x))
return natija
R = list(range(10_000))
SOZLASH = "from __main__ import yigindi_oddiy, yigindi_lokal, R"
print(f" {'Usul':<26} {'Vaqt':>12}")
print(" " + "─" * 42)
for nom, kod in [("Oddiy", "yigindi_oddiy(R)"),
("Lokal sukut bilan", "yigindi_lokal(R)")]:
vaqt = timeit.timeit(kod, setup=SOZLASH, number=200)
print(f" {nom:<26} {vaqt:>9.3f} s")
print("""
⚠️ Zamonaviy CPython da farq juda kichik (~2-5%).
Kod o'qilishi esa sezilarli yomonlashadi.
⭐ Bu hiylani ISHLATMANG — faqat isbotlangan tor joyda.
""")
print("\n=== 5. Xulosa: qachon ataylab ===")
print("""
┌──────────────────────────┬───────────────────────────────────┐
│ Maqsad │ To'g'ri usul │
├──────────────────────────┼───────────────────────────────────┤
│ Kesh │ @lru_cache / @cache ⭐ │
│ Chaqiruvlarni sanash │ Funksiya atributi yoki sinf ⭐ │
│ Oldindan hisoblash │ Modul konstantasi ⭐ │
│ Holat saqlash │ Sinf ⭐ │
│ Lokal nom (tezlik) │ Deyarli hech qachon kerak emas │
│ Yangi bo'sh konteyner │ =None + ichkarida yaratish ⭐ │
└──────────────────────────┴───────────────────────────────────┘
⭐ Har holat uchun aniqroq muqobil bor.
O'zgaruvchan sukut qiymat — niyatni YASHIRADI.
""")
print("\n=== 6. Kesh tozalash muammosi ===")
print(f" O'zgaruvchan sukut bilan:")
print(f" fib_kesh kesh hajmi: {len(fib_kesh.__defaults__[0])}")
print(f" Tozalash: fib_kesh.__defaults__[0].clear() ⚠️ hiyla")
fib_kesh.__defaults__[0].clear()
fib_kesh.__defaults__[0].update({0: 0, 1: 1})
print(f" Tozalangandan keyin: {len(fib_kesh.__defaults__[0])}")
print(f"\n @lru_cache bilan:")
print(f" Kesh: {fib_lru.cache_info()}")
fib_lru.cache_clear()
print(f" fib_lru.cache_clear()")
print(f" Kesh: {fib_lru.cache_info()} ✅ toza API")
print(f"\n Chegara bilan:")
@lru_cache(maxsize=3)
def kichik_kesh(n):
return n * 2
for i in range(6):
kichik_kesh(i)
print(f" @lru_cache(maxsize=3), 6 ta chaqiruv:")
print(f" {kichik_kesh.cache_info()}")
print(f" ⭐ Eng kam ishlatilganlar chiqarildi (LRU)")Natijaning muhim qismi:
=== 1. Kesh (memoizatsiya) ===
fib(30) = 832,040
Usul Vaqt
────────────────────────────────────────
Keshsiz (rekursiv) 284.12 ms
O`zgaruvchan sukut 0.0412 ms
@lru_cache 0.0284 ms
=== 2. Chaqiruvlarni sanash ===
Usul 1 2 3 Holatga kirish
────────────────────────────────────────────────────────────
Sukut ro'yxat 1 2 3 f.__defaults__[0][0]
Funksiya atributi 1 2 3 f.hisob
Sinf (__call__) 1 2 3 f.hisob
=== 6. Kesh tozalash muammosi ===
@lru_cache bilan:
Kesh: CacheInfo(hits=28, misses=31, maxsize=None, currsize=31)
fib_lru.cache_clear()
Kesh: CacheInfo(hits=0, misses=0, maxsize=None, currsize=0) ✅ toza APINima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Amaliy: konfiguratsiya funksiyalari
"""Sukut qiymatlar bilan to'g'ri API dizayni."""
from dataclasses import dataclass, field, replace
from datetime import datetime, timedelta
from enum import Enum
from typing import Any
print("=== Hisobot generatori ===\n")
_YOQ = object()
class Format(Enum):
MATN = "matn"
CSV = "csv"
JSON = "json"
@dataclass(frozen=True)
class Sozlamalar:
"""O'zgarmas sozlamalar — sukut qiymat sifatida xavfsiz."""
kenglik: int = 60
ajratgich: str = "│"
ramka: bool = True
raqamlar: bool = False
format: Format = Format.MATN
def __post_init__(self):
if not 20 <= self.kenglik <= 200:
raise ValueError(f"kenglik 20-200 oralig'ida: {self.kenglik}")
SUKUT_SOZLAMALAR = Sozlamalar() # ⭐ o'zgarmas — sukut sifatida xavfsiz
def hisobot(
yozuvlar: list[dict],
sarlavha: str = "HISOBOT",
*,
maydonlar: tuple[str, ...] = (), # ⭐ tuple, list emas
filtrlar: dict | None = None, # ⭐ None naqshi
sozlamalar: Sozlamalar = SUKUT_SOZLAMALAR, # ⭐ o'zgarmas obyekt
vaqt: datetime | None = None, # ⭐ None — har chaqiruvda yangi
chegara: int | Any = _YOQ, # ⭐ sentinel — None ham yaroqli
) -> str:
"""Yozuvlardan hisobot yaratadi.
Argumentlar:
yozuvlar: Ma'lumot yozuvlari
sarlavha: Hisobot sarlavhasi
maydonlar: Ko'rsatiladigan maydonlar (bo'sh — hammasi)
filtrlar: {maydon: qiymat} filtrlari
sozlamalar: Ko'rinish sozlamalari
vaqt: Hisobot vaqti (None — hozirgi vaqt)
chegara: Maksimal qatorlar (None — cheklovsiz, berilmasa — 10)
"""
# Sukutlarni hal qilish
filtrlar = filtrlar or {}
vaqt = vaqt if vaqt is not None else datetime.now()
if chegara is _YOQ:
chegara = 10
if not maydonlar and yozuvlar:
maydonlar = tuple(yozuvlar[0])
# Filtrlash
toza = [
y for y in yozuvlar
if all(y.get(k) == v for k, v in filtrlar.items())
]
if chegara is not None:
toza = toza[:chegara]
# Chiqarish
s = sozlamalar
if s.format is Format.CSV:
qatorlar = [",".join(maydonlar)]
qatorlar += [",".join(str(y.get(m, "")) for m in maydonlar) for y in toza]
return "\n".join(qatorlar)
if s.format is Format.JSON:
import json
return json.dumps(
{"sarlavha": sarlavha, "vaqt": vaqt.isoformat(), "yozuvlar": toza},
ensure_ascii=False, indent=2,
)
# MATN
kengliklar = {
m: max(len(str(m)), max((len(str(y.get(m, ""))) for y in toza), default=0))
for m in maydonlar
}
qatorlar = []
if s.ramka:
qatorlar.append(f"┌─ {sarlavha} ({vaqt:%Y-%m-%d %H:%M})")
qatorlar.append("│")
prefiks = "│ " if s.ramka else " "
sarlavha_qatori = f" {s.ajratgich} ".join(
f"{m:<{kengliklar[m]}}" for m in maydonlar
)
if s.raqamlar:
sarlavha_qatori = f"{'#':>3} {sarlavha_qatori}"
qatorlar.append(prefiks + sarlavha_qatori)
qatorlar.append(prefiks + "─" * len(sarlavha_qatori))
for i, y in enumerate(toza, 1):
qator = f" {s.ajratgich} ".join(
f"{str(y.get(m, '')):<{kengliklar[m]}}" for m in maydonlar
)
if s.raqamlar:
qator = f"{i:>3} {qator}"
qatorlar.append(prefiks + qator)
if s.ramka:
qatorlar.append("│")
qatorlar.append(f"└─ {len(toza)} yozuv")
return "\n".join(" " + q for q in qatorlar)
# ═══ NAMOYISH ═══
YOZUVLAR = [
{"id": 1, "ism": "Aziz", "bolim": "IT", "maosh": 7_000_000},
{"id": 2, "ism": "Bobur", "bolim": "HR", "maosh": 5_000_000},
{"id": 3, "ism": "Aziza", "bolim": "IT", "maosh": 8_000_000},
{"id": 4, "ism": "Dilnoza", "bolim": "Moliya", "maosh": 6_000_000},
{"id": 5, "ism": "Eldor", "bolim": "IT", "maosh": 9_000_000},
]
print("=== 1. Sukut qiymatlar bilan ===\n")
print(hisobot(YOZUVLAR))
print("\n\n=== 2. Maydonlarni tanlash ===\n")
print(hisobot(YOZUVLAR, "ISM VA MAOSH", maydonlar=("ism", "maosh")))
print("\n\n=== 3. Filtr bilan ===\n")
print(hisobot(YOZUVLAR, "IT BO'LIMI", filtrlar={"bolim": "IT"}))
print("\n\n=== 4. Sozlamalar bilan ===\n")
s = Sozlamalar(raqamlar=True, ajratgich="┃")
print(hisobot(YOZUVLAR, "RAQAMLANGAN", sozlamalar=s, chegara=3))
print("\n\n=== 5. ⭐ Sentinel: chegara ===\n")
VARIANTLAR = [
("chegara berilmadi", {}),
("chegara=2", {"chegara": 2}),
("chegara=None", {"chegara": None}),
]
for nom, kwargs in VARIANTLAR:
natija = hisobot(YOZUVLAR, format if False else "SINOV", **kwargs)
qatorlar_soni = natija.count("\n")
oxirgi = natija.strip().splitlines()[-1].strip()
print(f" {nom:<24} → {oxirgi}")
print("""
⭐ chegara=None — "cheklov yo'q" (5 yozuv)
chegara berilmadi — sukut 10 (5 yozuv, chunki jami 5)
chegara=2 — 2 yozuv
None ham YAROQLI qiymat, shuning uchun sentinel kerak.
""")
print("\n=== 6. Boshqa formatlar ===\n")
print(f" CSV:")
csv_s = Sozlamalar(format=Format.CSV)
for q in hisobot(YOZUVLAR, sozlamalar=csv_s, chegara=3,
maydonlar=("ism", "bolim", "maosh")).splitlines():
print(f" {q}")
print(f"\n JSON:")
json_s = Sozlamalar(format=Format.JSON)
natija = hisobot(YOZUVLAR, "TEST", sozlamalar=json_s, chegara=2,
vaqt=datetime(2026, 9, 8, 12, 0))
for q in natija.splitlines()[:10]:
print(f" {q}")
print(f" ...")
print("\n\n=== 7. Sukut qiymatlar tahlili ===\n")
import inspect
sig = inspect.signature(hisobot)
print(f" {'Parametr':<14} {'Sukut':<28} {'Xavfsizmi'}")
print(" " + "─" * 62)
OZGARUVCHAN = (list, dict, set, bytearray)
for nom, p in sig.parameters.items():
if p.default is inspect.Parameter.empty:
sukut, belgi = "(majburiy)", " "
else:
sukut = repr(p.default)
if len(sukut) > 26:
sukut = sukut[:24] + "…"
belgi = "⚠️" if isinstance(p.default, OZGARUVCHAN) else "✅"
print(f" {nom:<14} {sukut:<28} {belgi}")
print("""
⭐ Ishlatilgan naqshlar:
sarlavha = "HISOBOT" o'zgarmas satr
maydonlar = () o'zgarmas tuple (list emas)
filtrlar = None None naqshi
sozlamalar = SUKUT_SOZLAMALAR frozen dataclass — xavfsiz
vaqt = None har chaqiruvda yangi vaqt
chegara = _YOQ sentinel (None ham yaroqli)
""")
print("\n=== 8. Sozlamalarni o'zgartirish ===\n")
asosiy = Sozlamalar()
kengaytirilgan = replace(asosiy, kenglik=120, raqamlar=True)
csv_variant = replace(asosiy, format=Format.CSV)
print(f" asosiy = {asosiy}")
print(f" kengaytirilgan = {kengaytirilgan}")
print(f" csv_variant = {csv_variant}")
print(f"\n ⭐ frozen dataclass:")
print(f" • Sukut qiymat sifatida xavfsiz (o'zgartirib bo'lmaydi)")
print(f" • replace() bilan variantlar yaratiladi")
print(f" • __post_init__ da validatsiya")
try:
asosiy.kenglik = 100
except Exception as x:
print(f"\n asosiy.kenglik = 100 → ❌ {type(x).__name__}")
try:
Sozlamalar(kenglik=5)
except ValueError as x:
print(f" Sozlamalar(kenglik=5) → ❌ ValueError: {x}")Natijaning muhim qismi:
=== 1. Sukut qiymatlar bilan ===
┌─ HISOBOT (2026-09-14 13:34)
│
│ id │ ism │ bolim │ maosh
│ ────────────────────────────────────
│ 1 │ Aziz │ IT │ 7000000
│ 2 │ Bobur │ HR │ 5000000
│
└─ 5 yozuv
=== 7. Sukut qiymatlar tahlili ===
Parametr Sukut Xavfsizmi
──────────────────────────────────────────────────────────────
yozuvlar (majburiy)
sarlavha 'HISOBOT' ✅
maydonlar () ✅
filtrlar None ✅
sozlamalar Sozlamalar(kenglik=60, a… ✅
vaqt None ✅
chegara <object object at 0x0000… ✅Nima ko'rsatdi: 2.4, 2.7-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Sukut qiymat har chaqiruvda yaratiladi" | def paytida bir marta |
"def f(r=[]) har safar yangi ro'yxat" |
Bitta ro'yxat qayta ishlatiladi |
"Faqat list bilan muammo" |
dict, set, bytearray, obyektlar ham |
"if not r: r = [] yetarli" |
Bo'sh ro'yxatni ham almashtiradi. is None |
"tuple sukut har doim xavfsiz" |
(1, []) — ichida o'zgaruvchan |
"vaqt=datetime.now() ishlaydi" |
Vaqt def paytida qotib qoladi |
| "O'zgaruvchan sukut — har doim xato" | Ataylab kesh sifatida ishlatiladi (lekin muqobil yaxshiroq) |
"def f(a=1, b) mumkin" |
SyntaxError |
"def f(a, b=a) ishlaydi" |
NameError |
6. Keng tarqalgan xatolar va yechimlari
1. O'zgaruvchan sukut
def f(r=[]): # ❌
def f(r=None): # ✅
r = [] if r is None else r2. not r tekshiruvi
def f(r=None):
if not r: r = [] # ⚠️ [] ni ham almashtiradi
if r is None: r = [] # ✅3. Vaqt/tasodifiy sukut
def f(t=datetime.now()): ... # ⚠️ qotib qoladi
def f(t=random.random()): ... # ⚠️ bir xil qiymat
def f(t=None): # ✅
t = t or datetime.now()4. None ham yaroqli qiymat
def f(x=None): # ⚠️ None ni farqlab bo'lmaydi
_YOQ = object()
def f(x=_YOQ): # ✅5. Sukutsiz parametr sukutlidan keyin
def f(a=1, b): ... # ❌ SyntaxError
def f(a, b=1): ... # ✅
def f(*, a=1, b): ... # ✅ (* dan keyin)6. Tuple ichida o'zgaruvchan
def f(t=(1, [])): ... # ⚠️
def f(t=(1, ())): ... # ✅7. Sukut qiymat boshqa parametrga tayanishi
def f(a, b=a): ... # ❌ NameError
def f(a, b=None): # ✅
b = a if b is None else b8. Xavfli sukut
def ochish(yol, rejim="w"): ... # ⚠️ tasodifan o'chirish
def ochish(yol, rejim="r"): ... # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 7.2-dars (o'tilgan): argument uzatish, o'zgaruvchanlik
- 7.4-dars: nomli argumentlar
- 7.6-dars: faqat nomli argumentlar (
*) - 6.18-dars (o'tilgan): nusxa olish
- 6.5, 6.9-darslar (o'tilgan):
tuple,frozenset— xavfsiz sukutlar - 8-qism:
dataclass(frozen=True),field(default_factory=...) - 10-qism:
functools.lru_cache,partial - Linterlar:
ruffB006,pylintW0102
8. Eng yaxshi amaliyotlar
O'zgaruvchan sukut — hech qachon.
=None+ ichkarida yaratish.is None,not remas. Bo'sh ro'yxat — yaroqli qiymat.Noneham yaroqli bo'lsa — sentinel._YOQ = object().Vaqt, tasodif, ID — doim
None.defpaytida hisoblanmaslik uchun.O'zgarmas sukut qiymatlar:
(),frozenset(),"",0,None,frozen dataclass.Sukut — eng ko'p ishlatiladigan va xavfsiz holat.
rejim="r","w"emas.Linter ishlating.
ruffB006 buni avtomatik topadi.Kesh uchun
@lru_cache. O'zgaruvchan sukut niyatni yashiradi.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
def f1(x, r=[]): r.append(x); return r
def f2(x, r=None): r = r or []; r.append(x); return r
def f3(x, d={}): d[x] = 1; return d
def f4(x, t=()): return t + (x,)
def f5(x, s="") : return s + str(x)
1. print(f1(1), f1(2), f1(3))
2. print(f2(1), f2(2), f2(3))
3. print(f3(1), f3(2))
4. print(f4(1), f4(2))
5. print(f5(1), f5(2))
6. def g(x=[]): return len(x)
g().__class__; g([1,2]); print(g())
7. def h(a=1, b=2): return a, b
print(h.__defaults__)
8. def k(a, *, b=1, c=2): pass
print(k.__defaults__, k.__kwdefaults__)
9. import time
def m(t=time.time()): return t
a = m(); time.sleep(0.01); print(a == m())
10. def n(r=[]): r = r + [1]; return r
print(n(), n())
11. def p(t=(1, [])): t[1].append(1); return t
print(p(), p())
12. def q(x=None): return x is None
print(q(), q(None), q(0))Javoblar
[1, 2, 3] [1, 2, 3] [1, 2, 3]— tuzoq ikki qavat: uchala chaqiruv bitta ro'yxatni qaytaradi,printesa uni hammasi bajarilgandan keyin chiqaradi[1] [2] [3]—{1: 1, 2: 1} {1: 1, 2: 1}— ikkalasi ham bitta lug'at,printoxirgi holatini ko'rsatadi(1,) (2,)— tuple o'zgarmas1 2— str o'zgarmas0—g([1,2])sukutni o'zgartirmaydi(1, 2)None {'b': 1, 'c': 2}True— vaqtdefpaytida qotib qolgan[1] [1]—r = r + [1]yangi ro'yxat(1, [1, 1]) (1, [1, 1])— tuple o'zgarmas, lekin ichidagi list umumiy; ikkala chaqiruv bitta tuple'ni qaytaradiTrue True False
Vazifa 2: Xatolarni tuzating
1. def f(x, r=[]): r.append(x); return r
2. def f(x, d={}): d[x] = 1; return d
3. def f(t=datetime.now()): return t
4. def f(r=None):
if not r: r = [0]
return r
5. def f(a=1, b): return a, b
6. def f(a, b=a): return a, b
7. def f(x=None): ... # None ham yaroqli qiymat
8. def ochish(yol, rejim="w"): ...Javoblar
1. def f(x, r=None): r = [] if r is None else r; r.append(x); return r
2. def f(x, d=None): d = {} if d is None else d; d[x] = 1; return d
3. def f(t=None): t = t or datetime.now(); return t
4. if r is None: r = [0]
5. def f(a, b=1): return a, b # yoki def f(*, a=1, b)
6. def f(a, b=None): b = a if b is None else b; return a, b
7. _YOQ = object(); def f(x=_YOQ): ...
8. def ochish(yol, rejim="r"): ...Vazifa 3: Xavfsiz sukutlar kutubxonasi
Funksiyalar yozing (barchasi xavfsiz sukut bilan):
qosh(x, r=None)— ro'yxatga qo'shishguruhla(elementlar, kalit_f, natija=None)— guruhlashbirlashtir(d1, d2=None, chuqur=False)— lug'atlarni birlashtirishyozuv(matn, vaqt=None, daraja="INFO")— log yozuvisozla(kalit, qiymat=SENTINEL)—Noneham yaroqli- Har biri uchun test: ketma-ket chaqiruvlar mustaqilligini tekshiring
Vazifa 4: Sukut tekshiruvchi
Vosita yozing:
- Modul funksiyalarini skanerlaydi (
inspect) - O'zgaruvchan sukutlarni topadi (ichma-ich ham)
datetime.now(),random()kabi "vaqt bog'liq" sukutlarni topadi- Tuzatish taklifini beradi
ruff/pylintnatijasi bilan solishtiradi- Dekorator versiyasi:
@sukutlarni_tekshir
Vazifa 5: Sentinel kutubxonasi
Sentinel(nom)— nomli sentinel yaratuvchirepr,bool,copy/deepcopyto'g'ri ishlasinpicklebilan ishlasin (singleton saqlanishi)- Tur ko'rsatkichlari bilan (
TypeAlias) is_sentinel(x)yordamchisiPEP 661taklifi bilan solishtiring
Vazifa 6: Konfiguratsiya API
Funksiya yozing (10+ sozlama bilan):
- Majburiy va ixtiyoriy parametrlarni ajrating
*bilan nomli argumentlarni majburiy qilingfrozen dataclasssozlamalar obyektiNoneva sentinel farqini ko'rsating- Validatsiya
__post_init__da replace()bilan variantlar
Vazifa 7: O'ylash
Nega Python sukut qiymatni def paytida hisoblaydi, chaqiruv paytida emas? Bu xato emasmi?
Javob
Bu — ataylab qilingan dizayn qarori, xato emas. Lekin bahsli.
Dalillar "def paytida" foydasiga:
1. Izchillik: def — oddiy ifoda.
Pythonda def — bajariladigan buyruq, e'lon emas:
def f(x=hisobla()):
...def bajarilganda:
- Funksiya obyekti yaratiladi
- Sukut qiymatlar hisoblanadi (oddiy ifoda kabi)
- Nom bog'lanadi
Bu — boshqa hamma joydagi qoida bilan bir xil:
x = hisobla() # hozir hisoblanadi
d = {"a": hisobla()} # hozir
def f(x=hisobla()): ... # hozir — IZCHILAgar sukut qiymat kechiktirilsa, def maxsus qoidaga ega bo'lardi.
2. Tezlik.
Chaqiruv paytida hisoblansa, har chaqiruvda ish bajarilardi:
def f(x=[]): # har chaqiruvda yangi ro'yxat
def f(x=KATTA_KONSTANTA): # har chaqiruvda qidiruv
def f(x=hisobla()): # har chaqiruvda hisoblashFunksiya chaqiruvi — Pythonda eng ko'p bajariladigan amal. Uni sekinlashtirish jiddiy narx.
3. Yopilma semantikasi bilan mos.
def yaratuvchi(n):
def ichki(x=n): # n — yaratilish paytidagi qiymat
return x
return ichki
f1 = yaratuvchi(1)
f2 = yaratuvchi(2)
f1(), f2() # 1, 2 — har biri o'z qiymatini eslab qoldiBu — foydali xatti-harakat. Kechiktirilsa, n sikl o'zgaruvchisi bo'lganda kech bog'lanish muammosi chiqardi (6.15-dars).
4. Ba'zan ataylab kerak.
def f(_kesh={}): # kesh
def f(_hisob=[0]): # hisoblagich
def f(_len=len): # lokal nomDalillar "chaqiruv paytida" foydasiga:
1. Tuzoq — eng ko'p uchraydigan Python xatosi.
Har bir yangi Pythonchi bunga tushadi. StackOverflow'da minglab savol.
2. Intuitiv kutish boshqacha.
def f(r=[]):Ko'pchilik "har chaqiruvda yangi bo'sh ro'yxat" deb o'qiydi. Bu — tabiiy o'qish.
3. Boshqa tillar boshqacha:
- Ruby:
def f(r = [])— har chaqiruvda yangi - JavaScript:
function f(r = [])— har chaqiruvda yangi - C++:
void f(vector<int> r = {})— har chaqiruvda yangi
Python bu masalada yolg'iz.
Nega o'zgartirilmaydi:
1. Orqaga moslik.
Millionlab kod qatori mavjud xatti-harakatga tayanadi (kesh, hisoblagich, lokal nom hiylasi).
2. Muqobil sintaksis taklif qilingan:
def f(r=>[]): # PEP 671 — "late-bound defaults"
def f(r:=[]):PEP 671 (2021, Chris Angelico) aynan shuni taklif qildi:
def f(r=>[]):
# r har chaqiruvda yangi []Holat: draft. Muhokama davom etmoqda. Qarshi dalillar:
- Yangi sintaksis — o'rganish narxi
=Nonenaqshi ishlaydi va tanish- Ikki xil sukut — chalkashlik
3. Linterlar muammoni hal qiladi.
ruff B006, pylint W0102, flake8-bugbear B006Har qanday zamonaviy loyihada bu xato avtomatik topiladi.
Xulosa:
Bu — klassik trade-off:
| "def paytida" (Python) | "chaqiruv paytida" | |
|---|---|---|
| Izchillik | maxsus qoida | |
| Tezlik | har chaqiruvda | |
| Intuitivlik | ||
| Yopilma | tabiiy | murakkabroq |
| Kesh naqshi | mumkin |
Python izchillik va tezlikni intuitivlikdan ustun qo'ydi. Bu — Pythonning umumiy falsafasiga (def oddiy ifoda) mos, lekin yangi boshlovchilar uchun tuzoq.
Amaliy javob: =None naqshini o'rganing va linter ishlating. Bu — muammoni to'liq hal qiladi.
Nimani mustahkamlaydi: 2.2, 2.3, 2.5-bo'limlar.
Xulosa
Bu darsda sukut qiymatlarni va Pythonning eng mashhur tuzog'ini o'rgandik.
Eng muhim uch fikr:
Sukut qiymat
defpaytida bir marta hisoblanadi. U funksiya obyektida (__defaults__) saqlanadi va har chaqiruvda o'sha obyekt ishlatiladi. Shuning uchundef f(r=[])da barcha chaqiruvlar bitta ro'yxatni bo'lishadi.=Nonenaqshi — standart yechim.if r is None: r = []— va aynanis None,not remas: bo'sh ro'yxat foydalanuvchi bergan yaroqli qiymat bo'lishi mumkin.Noneham yaroqli bo'lsa — sentinel (_YOQ = object()).Vaqt, tasodif, o'zgaruvchan konteyner — hech qachon sukut sifatida.
datetime.now()defpaytida qotib qoladi. Xavfsiz sukutlar:None,(),frozenset(),"", sonlar,frozen dataclass.
Keyingi darsda nomli argumentlarni batafsil ko'ramiz: qachon ishlatish, o'qilishga ta'siri va API dizaynidagi roli.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!