IlmHamroh
Python kursi/Asoslar8/14-dars20 daqiqa
Mundarija (23)

3.8-dars: type() va turlarni bilish

3-QISM — ASOSLAR · 8-dars


1. Kirish va motivatsiya

1.3-darsda o'rgandik: Python dinamik turlangan til. Tur o'zgaruvchida emas, obyektda yashaydi (3.1-dars).

Bu — kuch. Lekin u savol tug'diradi: "Bu obyektning turi nima?"

Bu savol amaliyotda doim chiqadi:

python
qiymat = malumot_olish()
# Bu son? Satr? Ro'yxat? None?
text
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Xatoni tuzatish uchun avval nima bilan ishlayotganingizni bilish kerak.

Bu darsda:

  • type() va isinstance() — farqi va qaysi birini qachon ishlatish
  • O'rdak turlashi (duck typing) — Pythonning falsafasi
  • hasattr() — "bu obyekt shu ishni qila oladimi?"
  • EAFP va LBYL — ikki xil dasturlash uslubi
  • type() ning yashirin ikkinchi vazifasi

Dars oxirida siz turlarni tekshirishni emas, ular haqida to'g'ri o'ylashni o'rganasiz. Chunki Pythonda tur tekshirish ko'pincha noto'g'ri yechim.


2. Nazariya — chuqur tushuntirish

2.1. type() — turni bilish

python
print(type(42))                 # <class 'int'>
print(type(3.14))               # <class 'float'>
print(type("salom"))            # <class 'str'>
print(type(True))               # <class 'bool'>
print(type(None))               # <class 'NoneType'>
print(type([1, 2]))             # <class 'list'>
print(type((1, 2)))             # <class 'tuple'>
print(type({1, 2}))             # <class 'set'>
print(type({"a": 1}))           # <class 'dict'>
print(type(print))              # <class 'builtin_function_or_method'>
print(type(type))               # <class 'type'>

type() sinf obyektini qaytaradi, satr emas:

python
t = type(42)
print(t)                        # <class 'int'>
print(t is int)                 # True
print(t.__name__)               # 'int'    ← nomi kerak bo'lsa
print(t(3.9))                   # 3        ← chaqirish ham mumkin!

Nomni olish uchun .__name__:

python
qiymatlar = [42, 3.14, "salom", True, None, [1], (1,), {1}, {"a": 1}]

for q in qiymatlar:
    print(f"{repr(q):<12} → {type(q).__name__}")
text
42           → int
3.14         → float
'salom'      → str
True         → bool
None         → NoneType
[1]          → list
(1,)         → tuple
{1}          → set
{'a': 1}     → dict

2.2. isinstance() — meros bilan ishlaydi

python
print(isinstance(42, int))          # True
print(isinstance("salom", str))     # True
print(isinstance(42, str))          # False

type() bilan farqi — meros:

python
print(type(True) == int)            # False  ← bool int emas?
print(isinstance(True, int))        # True   ← lekin int dan meros!

3.5-darsda ko'rgandik: bool — int ning bolasi. type() aniq turni tekshiradi, isinstance() esa meros zanjirini ham hisobga oladi.

Bu — nima uchun isinstance() afzal ko'riladi:

python
class Hayvon:
    pass

class It(Hayvon):
    pass

it = It()

print(type(it) == Hayvon)           # False — aniq tur It
print(isinstance(it, Hayvon))       # True  — It ham Hayvon

It — Hayvon ning turi. isinstance() buni tushunadi.

Bir nechta turni tekshirish:

python
qiymat = 42

print(isinstance(qiymat, (int, float)))     # True — juftlik bering
print(isinstance(qiymat, int | float))      # True — 3.10+ sintaksisi

Sinf uchun — issubclass():

python
print(issubclass(bool, int))        # True
print(issubclass(int, object))      # True — hamma narsa object dan
print(issubclass(It, Hayvon))       # True

Qoida:

Tur tekshirish kerak bo'lsa — isinstance(). type() == faqat aniq tur kerak bo'lgan kam holatlarda.

2.3. O'rdak turlashi (duck typing)

Bu — Pythonning asosiy falsafalaridan biri:

"Agar u o'rdakdek yursa va o'rdakdek qaqillasa — u o'rdak."

Ya'ni: obyektning turi emas, nima qila olishi muhim.

python
def yigindi(elementlar):
    jami = 0
    for element in elementlar:
        jami += element
    return jami


print(yigindi([1, 2, 3]))           # 6  — ro'yxat
print(yigindi((1, 2, 3)))           # 6  — juftlik
print(yigindi({1, 2, 3}))           # 6  — to'plam
print(yigindi(range(1, 4)))         # 6  — diapazon
print(yigindi(x for x in [1, 2, 3]))# 6  — generator

Funksiya turni umuman tekshirmadi. U faqat "iteratsiya qilinadimi?" degan savolga tayandi.

Solishtiring — turni tekshiradigan versiya:

python
def yigindi_yomon(elementlar):
    if not isinstance(elementlar, list):        # ❌
        raise TypeError("Ro'yxat kerak")
    ...

Bu funksiya juftlik, to'plam, generator bilan ishlamaydi — hech qanday sabab yo'q holda.

O'rdak turlashi nima beradi:

Foyda Izoh
Moslashuvchanlik Har qanday mos obyekt ishlaydi
Kengaytiriluvchanlik O'z sinfingiz ham ishlaydi
Test qilish oson Soxta obyekt (mock) berish mumkin
Kam kod Tekshiruvlar kerak emas

O'z sinfingiz bilan:

python
class Hisoblagich:
    def __init__(self, oxiri):
        self.oxiri = oxiri

    def __iter__(self):
        return iter(range(1, self.oxiri + 1))


print(yigindi(Hisoblagich(3)))      # 6 — ishlaydi!

Hisoblagich ro'yxat emas, lekin iteratsiya qilinadi. Shuning uchun yigindi u bilan ishlaydi.

10-qismda __iter__ va boshqa protokollarni batafsil o'rganamiz.

2.4. hasattr() — imkoniyatni tekshirish

Turni emas, imkoniyatni tekshirish — o'rdak turlashiga mos yondashuv:

python
def matnga_aylantir(obyekt):
    if hasattr(obyekt, "matn_korinishi"):
        return obyekt.matn_korinishi()
    return str(obyekt)
python
print(hasattr("salom", "upper"))        # True
print(hasattr(42, "upper"))             # False
print(hasattr([1, 2], "append"))        # True
print(hasattr((1, 2), "append"))        # False — juftlik o'zgarmas

Bog'liq funksiyalar:

python
matn = "salom"

print(getattr(matn, "upper"))               # <built-in method upper>
print(getattr(matn, "upper")())             # 'SALOM'
print(getattr(matn, "yoq", "sukut"))        # 'sukut' — xato yo'q
print(callable(matn.upper))                 # True — chaqirilishi mumkin
print(callable(matn))                       # False

Amaliy misol:

python
def uzunlik(obyekt):
    """Obyekt uzunligini xavfsiz qaytaradi."""
    if hasattr(obyekt, "__len__"):
        return len(obyekt)
    return None


print(uzunlik("salom"))         # 5
print(uzunlik([1, 2, 3]))       # 3
print(uzunlik(42))              # None

2.5. EAFP va LBYL — ikki uslub

Pythonda ikki xil dasturlash uslubi bor:

LBYL — "Look Before You Leap" (sakrashdan oldin qara):

python
if isinstance(qiymat, str) and qiymat.isdigit():
    son = int(qiymat)
else:
    son = 0

EAFP — "Easier to Ask Forgiveness than Permission" (ruxsat so'ragandan ko'ra kechirim so'rash oson):

python
try:
    son = int(qiymat)
except (ValueError, TypeError):
    son = 0

Python EAFP ni afzal ko'radi. Nega?

Sabab Izoh
Kamroq kod Barcha holatni oldindan o'ylash shart emas
Tezroq (odatda) Xato kam bo'lsa, try deyarli bepul
Poyga shartlari yo'q Tekshirish va ishlatish orasida holat o'zgarishi mumkin
O'rdak turlashiga mos Turni emas, natijani tekshiradi

Poyga sharti misoli:

python
# ❌ LBYL — fayl tekshiruv va ochish orasida o'chirilishi mumkin
import os
if os.path.exists("fayl.txt"):
    with open("fayl.txt") as f:         # bu yerda fayl yo'q bo'lishi mumkin!
        ...

# ✅ EAFP
try:
    with open("fayl.txt") as f:
        ...
except FileNotFoundError:
    ...

LBYL qachon yaxshi:

  • Xato tez-tez bo'lsa (istisno qimmat)
  • Tekshiruv arzon va aniq bo'lsa
  • Bir necha shartni birdan tekshirish kerak bo'lsa
python
# LBYL bu yerda tabiiy
if 0 <= indeks < len(royxat):
    element = royxat[indeks]

9-qismda istisnolarni to'liq o'rganamiz.

2.6. Tur tekshirish qachon kerak

O'rdak turlashi yaxshi, lekin ba'zan tur tekshirish zarur:

1. Turli tur uchun turli mantiq

python
def formatla(qiymat) -> str:
    if isinstance(qiymat, bool):        # bool int dan OLDIN!
        return "Ha" if qiymat else "Yo'q"
    if isinstance(qiymat, (int, float)):
        return f"{qiymat:,.2f}"
    if isinstance(qiymat, str):
        return qiymat.strip()
    if isinstance(qiymat, (list, tuple)):
        return ", ".join(formatla(e) for e in qiymat)
    if qiymat is None:
        return "—"
    return str(qiymat)

Diqqat: bool tekshiruvi int dan oldin bo'lishi kerak — chunki isinstance(True, int) True beradi.

2. Rekursiv tuzilmalar

python
def chuqur_yigindi(malumot):
    """Ichma-ich ro'yxatlardagi barcha sonni qo'shadi."""
    jami = 0
    for element in malumot:
        if isinstance(element, (list, tuple)):
            jami += chuqur_yigindi(element)
        else:
            jami += element
    return jami


print(chuqur_yigindi([1, [2, 3], [4, [5, 6]]]))     # 21

3. Ommaviy API chegarasida

python
def yaratish(nom: str, yosh: int):
    if not isinstance(nom, str):
        raise TypeError(f"nom str bo'lishi kerak, {type(nom).__name__} berildi")
    ...

Kutubxona yozayotganda foydalanuvchiga aniq xato berish foydali.

4. None ni tekshirish — bu ham tur tekshiruvi:

python
if qiymat is None:      # ✅ eng ko'p uchraydigan holat

2.7. type() ning ikkinchi vazifasi

type() uchta argument bilan chaqirilsa — yangi sinf yaratadi:

python
# Odatiy usul
class Odam:
    tur = "inson"

    def salomlash(self):
        return "Salom!"


# type() bilan — bir xil natija
Odam2 = type("Odam2", (), {
    "tur": "inson",
    "salomlash": lambda self: "Salom!",
})

o = Odam2()
print(o.tur)                # inson
print(o.salomlash())        # Salom!
print(type(Odam2))          # <class 'type'>

Bu — metasinflar mavzusi (10-qism). Hozircha faqat bilib qo'ying: Pythonda sinflar ham obyekt va ularni dinamik yaratish mumkin.

Muhim natija: hamma narsa object dan meros:

python
print(isinstance(42, object))       # True
print(isinstance("a", object))      # True
print(isinstance(int, object))      # True
print(isinstance(type, object))     # True

Va hamma narsaning turi — oxir-oqibat type:

python
print(type(42))             # <class 'int'>
print(type(int))            # <class 'type'>
print(type(type))           # <class 'type'>  ← o'ziga qaytadi

2.8. Turlar iyerarxiyasi

python
print(int.__mro__)
text
(<class 'int'>, <class 'object'>)

__mro__ — "Method Resolution Order", meros zanjiri (8-qism).

python
print(bool.__mro__)
text
(<class 'bool'>, <class 'int'>, <class 'object'>)

Asosiy turlar iyerarxiyasi:

text
object
├── int
│   └── bool
├── float
├── complex
├── str
├── bytes
├── list
├── tuple
├── dict
├── set
│   └── frozenset
├── NoneType
└── ...

Mavhum turlar (collections.abc) — imkoniyat bo'yicha guruhlash:

python
from collections.abc import Iterable, Sequence, Mapping

print(isinstance([1, 2], Iterable))     # True
print(isinstance("abc", Iterable))      # True
print(isinstance(42, Iterable))         # False

print(isinstance([1, 2], Sequence))     # True — indekslanadi
print(isinstance({1, 2}, Sequence))     # False — to'plam indekslanmaydi

print(isinstance({"a": 1}, Mapping))    # True

Bu — o'rdak turlashining rasmiylashtirilgan shakli:

python
def qayta_ishla(malumot):
    if isinstance(malumot, Mapping):        # ✅ dict, OrderedDict, ...
        ...
    elif isinstance(malumot, Iterable):     # ✅ list, tuple, set, generator
        ...

isinstance(x, list) dan yaxshiroq — chunki u boshqa mos turlarni ham qamrab oladi.

2.9. Tur ishoralari bilan bog'liqlik

python
def qosh(a: int, b: int) -> int:
    return a + b

Muhim: tur ishoralari ishlash paytida tekshirilmaydi:

python
print(qosh("a", "b"))       # 'ab' — xato yo'q!

Python ularni e'tiborsiz qoldiradi. Ular faqat:

  • Pylance / mypy uchun (2.7-dars)
  • Hujjat sifatida
  • IDE avtomatik to'ldirishi uchun

Ishlash paytida ko'rish mumkin:

python
print(qosh.__annotations__)
text
{'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}

Ba'zi kutubxona (pydantic, FastAPI) bulardan foydalanib haqiqiy tekshirish qiladi. Lekin bu — kutubxonaning ishi, Pythonning emas.

13-qismda batafsil.


3. Tez ma'lumotnoma

Turni bilish

python
type(x)                 sinf obyekti
type(x).__name__        nomi (satr)
isinstance(x, int)      meros bilan ✅ TAVSIYA
type(x) == int          aniq tur (kam kerak)
issubclass(A, B)        sinflar uchun

Imkoniyatni tekshirish

python
hasattr(x, "metod")             metod bormi
getattr(x, "metod", sukut)      xavfsiz olish
callable(x)                     chaqirilishi mumkinmi

Bir nechta tur

python
isinstance(x, (int, float))     juftlik
isinstance(x, int | float)      3.10+

Mavhum turlar

python
from collections.abc import Iterable, Sequence, Mapping
isinstance(x, Iterable)         iteratsiya qilinadimi
isinstance(x, Sequence)         indekslanadimi
isinstance(x, Mapping)          lug'atga o'xshashmi

Uslublar

text
LBYL:  if isinstance(x, str): ...       tekshirib keyin qil
EAFP:  try: ... except TypeError: ...   qil, xato bo'lsa ushla  ← Python usuli

Diqqat

python
isinstance(True, int)   → True     (bool int dan meros)
bool ni int dan OLDIN tekshiring

4. Batafsil misollar

Misol 1 — type() va isinstance() farqi

python
class Hayvon:
    pass


class It(Hayvon):
    pass


class Kuchuk(It):
    pass


obyektlar = [42, 3.14, True, "matn", None, [1], Hayvon(), It(), Kuchuk()]

print(f"{'Obyekt':<16} {'type().__name__':<18} {'type()==int':<12} {'isinstance(int)'}")
print("-" * 62)

for o in obyektlar:
    print(
        f"{repr(o)[:15]:<16} "
        f"{type(o).__name__:<18} "
        f"{str(type(o) == int):<12} "
        f"{isinstance(o, int)}"
    )

print("\n=== Meros zanjiri ===")
for sinf in [bool, It, Kuchuk]:
    zanjir = " → ".join(k.__name__ for k in sinf.__mro__)
    print(f"  {sinf.__name__:<10} {zanjir}")

print("\n=== isinstance meros bilan ishlaydi ===")
k = Kuchuk()
print(f"  isinstance(kuchuk, Kuchuk)  = {isinstance(k, Kuchuk)}")
print(f"  isinstance(kuchuk, It)      = {isinstance(k, It)}")
print(f"  isinstance(kuchuk, Hayvon)  = {isinstance(k, Hayvon)}")
print(f"  isinstance(kuchuk, object)  = {isinstance(k, object)}")
print(f"  type(kuchuk) == Hayvon      = {type(k) == Hayvon}")
text
Obyekt           type().__name__    type()==int  isinstance(int)
--------------------------------------------------------------
42               int                True         True
3.14             float              False        False
True             bool               False        True
'matn'           str                False        False
None             NoneType           False        False
[1]              list               False        False
<__main__.Hayv   Hayvon             False        False
<__main__.It o   It                 False        False
<__main__.Kuch   Kuchuk             False        False

=== Meros zanjiri ===
  bool       bool → int → object
  It         It → Hayvon → object
  Kuchuk     Kuchuk → It → Hayvon → object

=== isinstance meros bilan ishlaydi ===
  isinstance(kuchuk, Kuchuk)  = True
  isinstance(kuchuk, It)      = True
  isinstance(kuchuk, Hayvon)  = True
  isinstance(kuchuk, object)  = True
  type(kuchuk) == Hayvon      = False

Eng muhim qator: True uchun type() == int → False, lekin isinstance(int) → True.

Nima ko'rsatdi: 2.1, 2.2, 2.8-bo'limlar.

Misol 2 — O'rdak turlashi amalda

python
"""Bir funksiya — ko'p turdagi ma'lumot."""


def statistika(malumot):
    """Har qanday iteratsiya qilinadigan sonli to'plam uchun."""
    elementlar = list(malumot)          # bir marta ro'yxatga aylantiramiz
    if not elementlar:
        return None
    return {
        "soni": len(elementlar),
        "jami": sum(elementlar),
        "eng_katta": max(elementlar),
        "eng_kichik": min(elementlar),
        "ortacha": sum(elementlar) / len(elementlar),
    }


class HaftaKunlari:
    """O'z sinfimiz — u ham iteratsiya qilinadi."""

    def __init__(self, ish_soatlari):
        self.soatlar = ish_soatlari

    def __iter__(self):
        return iter(self.soatlar)


manbalar = [
    ("ro'yxat", [8, 7, 9, 8, 6]),
    ("juftlik", (8, 7, 9, 8, 6)),
    ("to'plam", {8, 7, 9, 6}),
    ("diapazon", range(6, 11)),
    ("generator", (x for x in [8, 7, 9, 8, 6])),
    ("lug'at qiymatlari", {"du": 8, "se": 7, "cho": 9}.values()),
    ("o'z sinfimiz", HaftaKunlari([8, 7, 9, 8, 6])),
]

for nom, manba in manbalar:
    natija = statistika(manba)
    print(f"{nom:<20} soni={natija['soni']}  jami={natija['jami']}  "
          f"o'rtacha={natija['ortacha']:.1f}")
text
ro'yxat              soni=5  jami=38  o'rtacha=7.6
juftlik              soni=5  jami=38  o'rtacha=7.6
to'plam              soni=4  jami=30  o'rtacha=7.5
diapazon             soni=5  jami=40  o'rtacha=8.0
generator            soni=5  jami=38  o'rtacha=7.6
lug'at qiymatlari    soni=3  jami=24  o'rtacha=8.0
o'z sinfimiz         soni=5  jami=38  o'rtacha=7.6

Funksiya hech qanday tur tekshirmadi — va yetti xil manba bilan ishladi. Shu jumladan biz o'zimiz yaratgan sinf bilan ham.

Agar if not isinstance(malumot, list): raise TypeError(...) yozganimizda, faqat birinchisi ishlardi.

Nima ko'rsatdi: 2.3-bo'lim. Bu — Python falsafasining amaliy ko'rinishi.

Misol 3 — EAFP va LBYL solishtiruvi

python
"""Bir masala — ikki uslub."""

import time

MALUMOTLAR = ["42", "3.14", "salom", "", None, "100", [1, 2], "0", "-7"]


def songa_lbyl(qiymat):
    """LBYL — oldin tekshiramiz."""
    if qiymat is None:
        return 0
    if isinstance(qiymat, (int, float)):
        return qiymat
    if not isinstance(qiymat, str):
        return 0
    matn = qiymat.strip()
    if not matn:
        return 0
    if matn.lstrip("-").replace(".", "", 1).isdigit():
        return float(matn) if "." in matn else int(matn)
    return 0


def songa_eafp(qiymat):
    """EAFP — urinib ko'ramiz."""
    try:
        return int(qiymat)
    except (ValueError, TypeError):
        pass
    try:
        return float(qiymat)
    except (ValueError, TypeError):
        return 0


print(f"{'Kirish':<12} {'LBYL':<10} {'EAFP'}")
print("-" * 32)
for m in MALUMOTLAR:
    print(f"{repr(m):<12} {songa_lbyl(m)!r:<10} {songa_eafp(m)!r}")

print("\n=== Kod uzunligi ===")
print(f"  LBYL: 12 qator, 5 ta shart")
print(f"  EAFP:  7 qator, 2 ta try")

print("\n=== Tezlik (ko'p xato bo'lmasa) ===")
TOZA = ["42"] * 100_000

boshlandi = time.perf_counter()
for m in TOZA:
    songa_lbyl(m)
vaqt_lbyl = time.perf_counter() - boshlandi

boshlandi = time.perf_counter()
for m in TOZA:
    songa_eafp(m)
vaqt_eafp = time.perf_counter() - boshlandi

print(f"  LBYL: {vaqt_lbyl * 1000:.1f} ms")
print(f"  EAFP: {vaqt_eafp * 1000:.1f} ms  ← tezroq")
text
Kirish       LBYL       EAFP
--------------------------------
'42'         42         42
'3.14'       3.14       3.14
'salom'      0          0
''           0          0
None         0          0
'100'        100        100
[1, 2]       0          0
'0'          0          0
'-7'         -7         -7

=== Kod uzunligi ===
  LBYL: 12 qator, 5 ta shart
  EAFP:  7 qator, 2 ta try

=== Tezlik (ko'p xato bo'lmasa) ===
  LBYL: 71.3 ms
  EAFP: 25.4 ms  ← tezroq

EAFP yutdi: qisqaroq, tezroq va to'liqroq (LBYL versiyasida "1.2.3" kabi holatlar uchun qo'shimcha shart kerak bo'lardi).

Lekin: agar ma'lumotning 90 foizi noto'g'ri bo'lsa, LBYL tezroq bo'ladi — istisno ko'tarish qimmat. Kontekstni bilib tanlang.

Nima ko'rsatdi: 2.5-bo'lim.

Misol 4 — Universal formatlovchi

python
"""Har qanday qiymatni chiroyli ko'rsatadigan funksiya."""

from collections.abc import Mapping, Sequence
from datetime import date, datetime


def formatla(qiymat, chuqurlik: int = 0) -> str:
    """Qiymatni o'qiladigan matnga aylantiradi."""
    chekinish = "  " * chuqurlik

    # ⚠️ bool INT dan OLDIN — chunki isinstance(True, int) → True
    if isinstance(qiymat, bool):
        return "Ha" if qiymat else "Yo'q"

    if qiymat is None:
        return "—"

    if isinstance(qiymat, int):
        return f"{qiymat:,}"

    if isinstance(qiymat, float):
        return f"{qiymat:,.2f}"

    if isinstance(qiymat, str):
        return qiymat.strip() or "(bo'sh)"

    if isinstance(qiymat, (date, datetime)):
        return qiymat.strftime("%d.%m.%Y")

    if isinstance(qiymat, Mapping):
        if not qiymat:
            return "(bo'sh lug'at)"
        qatorlar = [
            f"{chekinish}  {k}: {formatla(v, chuqurlik + 1)}"
            for k, v in qiymat.items()
        ]
        return "\n" + "\n".join(qatorlar)

    if isinstance(qiymat, Sequence):
        if not qiymat:
            return "(bo'sh ro'yxat)"
        qatorlar = [
            f"{chekinish}  • {formatla(e, chuqurlik + 1)}" for e in qiymat
        ]
        return "\n" + "\n".join(qatorlar)

    # Noma'lum tur — o'rdak turlashiga qaytamiz
    if hasattr(qiymat, "__str__"):
        return str(qiymat)

    return f"<{type(qiymat).__name__}>"


malumot = {
    "ism": "Sarvarbek",
    "yosh": 25,
    "faol": True,
    "balans": 1_250_000.5,
    "sana": date(2026, 9, 7),
    "izoh": None,
    "teglar": ["python", "dasturlash", "wisar"],
    "manzil": {
        "shahar": "Toshkent",
        "tuman": "Chilonzor",
        "indeks": 100115,
    },
    "bosh_royxat": [],
}

print("┌─ MA'LUMOT")
for kalit, qiymat in malumot.items():
    print(f"│ {kalit:<12} {formatla(qiymat)}")
print("└─")
text
┌─ MA'LUMOT
│ ism          Sarvarbek
│ yosh         25
│ faol         Ha
│ balans       1,250,000.50
│ sana         07.09.2026
│ izoh         —
│ teglar
    • python
    • dasturlash
    • wisar
│ manzil
    shahar: Toshkent
    tuman: Chilonzor
    indeks: 100,115
│ bosh_royxat  (bo'sh ro'yxat)
└─

Kodda ko'rish kerak:

  • bool tekshiruvi int dan oldin — eng muhim tafsilot
  • Mapping va Sequence — aniq turlar emas, imkoniyatlar (2.8-bo'lim)
  • Rekursiv chaqiruv — ichma-ich tuzilmalar uchun
  • hasattr bilan zaxira yechim (2.4-bo'lim)

Diqqat: str ham Sequence — shuning uchun uni oldinroq tekshirdik. Aks holda satr belgilarga bo'linib ketardi.

Nima ko'rsatdi: 2.2, 2.4, 2.6, 2.8-bo'limlar birgalikda.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"type(x) == int — to'g'ri usul" isinstance() afzal — meros bilan ishlaydi
"isinstance(True, int) → False" True! bool int dan meros
"Tur tekshirish — yaxshi amaliyot" Pythonda odatda noto'g'ri. O'rdak turlashi afzal
"type() satr qaytaradi" Sinf obyektini. Nomi uchun .__name__
"Tur ishoralari ishlash paytida tekshiriladi" Yo'q — Python ularni e'tiborsiz qoldiradi
"LBYL xavfsizroq" Pythonda EAFP idiomatik va ko'pincha tezroq
"hasattr sekin" Tez. Va o'rdak turlashiga mos
"Har bir funksiya turni tekshirishi kerak" Aksincha — bu moslashuvchanlikni yo'qotadi

6. Keng tarqalgan xatolar va yechimlari

1. bool ni int dan keyin tekshirish

python
def formatla(x):
    if isinstance(x, int):          # ❌ True ham bu yerga tushadi
        return f"{x:,}"
    if isinstance(x, bool):         # hech qachon yetib kelmaydi
        return "Ha" if x else "Yo'q"

print(formatla(True))               # '1' — noto'g'ri!

Yechim: bool ni birinchi tekshiring.

2. str ni Sequence dan keyin tekshirish

python
from collections.abc import Sequence

def qayta_ishla(x):
    if isinstance(x, Sequence):     # ❌ satr ham Sequence!
        return [qayta_ishla(e) for e in x]
    return x

print(qayta_ishla("abc"))           # cheksiz rekursiya xavfi

Yechim:

python
if isinstance(x, str):
    return x
if isinstance(x, Sequence):
    ...

3. type() ni satr bilan solishtirish

python
if type(x) == "int":                # ❌ hech qachon True bo'lmaydi
if type(x).__name__ == "int":       # ✅ ishlaydi, lekin
if isinstance(x, int):              # ✅ to'g'ri usul

4. Ortiqcha tur tekshirish

python
def yigindi(sonlar):
    if not isinstance(sonlar, list):    # ❌ juftlik, generator ishlamaydi
        raise TypeError("Ro'yxat kerak")
    return sum(sonlar)

def yigindi(sonlar):                    # ✅ o'rdak turlashi
    return sum(sonlar)

5. hasattr ni try o'rniga noto'g'ri ishlatish

python
if hasattr(x, "metod"):
    x.metod()                       # metod ichida xato bo'lsa baribir qulaydi

hasattr faqat mavjudligini tekshiradi, ishlashini emas.

6. isinstance ga ro'yxat berish

python
isinstance(x, [int, str])           # ❌ TypeError
isinstance(x, (int, str))           # ✅ juftlik
isinstance(x, int | str)            # ✅ 3.10+

7. Tur ishoralariga ishonish

python
def f(x: int) -> int:
    return x * 2

print(f("ab"))                      # 'abab' — xato yo'q!

Tur ishoralari — hujjat, majburlash emas. Haqiqiy tekshirish kerak bo'lsa pydantic (13-qism).


7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 3.9-dars: turlarni aylantirish — int(), str(), float()
  • 6-qism: ro'yxat/lug'at/to'plam farqi va Sequence/Mapping
  • 7-qism: funksiyalarga har qanday tur berish
  • 8-qism: sinflar, meros, isinstance ning haqiqiy kuchi
  • 9-qism: EAFP — istisnolar bilan ishlash
  • 13-qism: tur ishoralari, mypy, tur toraytirish
  • 10-qism: metasinflar, __iter__, protokollar
  • 13-qism: pydantic — ishlash paytida tur tekshirish

8. Eng yaxshi amaliyotlar

  1. isinstance() ishlating, type() == emas. Meros bilan to'g'ri ishlaydi.

  2. Tur tekshirishdan qoching. Avval o'ylang: "bu rostdan kerakmi yoki o'rdak turlashi yetarlimi?"

  3. bool ni int dan oldin, str ni Sequence dan oldin tekshiring. Bu ikki tartib xatosi eng ko'p uchraydi.

  4. EAFP ni afzal ko'ring. try/except — Python idiomasi, if isinstance(...) emas.

  5. Aniq turlar o'rniga mavhum turlarni ishlating. Iterable, Sequence, Mapping — list, dict dan moslashuvchan.

  6. Tur ishoralarini yozing, lekin ularga ishonmang. Ular — hujjat va IDE uchun, majburlash uchun emas.

  7. hasattr ni imkoniyat tekshirish uchun ishlating. Turdan ko'ra "nima qila oladi" muhimroq.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  type(42) == int
2.  type(True) == int
3.  isinstance(True, int)
4.  isinstance(42, bool)
5.  isinstance(3.14, (int, float))
6.  issubclass(bool, int)
7.  type(type)
8.  isinstance([], object)
9.  type([1,2]).__name__
10. isinstance("abc", Iterable)   # from collections.abc
Javoblar
  1. True
  2. False — aniq tur bool
  3. True — meros
  4. False — int bool emas
  5. True
  6. True
  7. <class 'type'>
  8. True — hamma narsa object
  9. 'list'
  10. True — satr iteratsiya qilinadi

Vazifa 2: Xatoni toping

python
def tavsif(qiymat):
    if isinstance(qiymat, int):
        return f"Butun son: {qiymat}"
    if isinstance(qiymat, bool):
        return f"Mantiqiy: {qiymat}"
    return "Boshqa"

print(tavsif(True))
  1. Nima chiqadi?
  2. Nega?
  3. Tuzating.
Javob

Butun son: True — chunki isinstance(True, int) True beradi va birinchi shart ishlaydi.

Tuzatish: bool ni birinchi tekshiring (2.6-bo'lim).

Vazifa 3: O'rdak turlashi

ortacha(malumot) funksiyasini yozing. U quyidagilar bilan ishlashi kerak:

python
ortacha([1, 2, 3])
ortacha((1, 2, 3))
ortacha({1, 2, 3})
ortacha(range(1, 4))
ortacha({"a": 1, "b": 2}.values())
ortacha(x * 2 for x in [1, 2, 3])

Hech qanday isinstance ishlatmang.

Yechim
python
def ortacha(malumot):
    elementlar = list(malumot)      # generator ham ishlasin
    if not elementlar:
        return None
    return sum(elementlar) / len(elementlar)

list() ga aylantirish muhim — generator bir marta o'qiladi, len() ham, sum() ham kerak.

Vazifa 4: EAFP ga o'tkazish

LBYL uslubidagi kodni EAFP ga aylantiring:

python
def qiymat_olish(malumot, kalit, indeks):
    if isinstance(malumot, dict):
        if kalit in malumot:
            qiymat = malumot[kalit]
            if isinstance(qiymat, (list, tuple)):
                if 0 <= indeks < len(qiymat):
                    return qiymat[indeks]
    return None
Yechim
python
def qiymat_olish(malumot, kalit, indeks):
    try:
        return malumot[kalit][indeks]
    except (KeyError, IndexError, TypeError):
        return None

7 qator → 4 qator. Va u ko'proq turdagi obyekt bilan ishlaydi.

Vazifa 5: Tur tekshiruvchi

tur_hisoboti(malumot) funksiyasini yozing. Ro'yxat berilganda har bir turdagi element nechta ekanini qaytarsin:

python
malumot = [1, "a", 2.5, True, None, [1], {"a": 1}, 3, "b"]

Kutilgan natija:

text
int:      2      ← True hisobga olinmasin
bool:     1
str:      2
float:    1
NoneType: 1
list:     1
dict:     1
Yechim
python
def tur_hisoboti(malumot) -> dict[str, int]:
    hisob: dict[str, int] = {}
    for element in malumot:
        nom = type(element).__name__        # ANIQ tur — bool ajraladi
        hisob[nom] = hisob.get(nom, 0) + 1
    return hisob


for nom, soni in sorted(tur_hisoboti(malumot).items()):
    print(f"{nom + ':':<10} {soni}")

Bu — type() ning isinstance() dan yaxshiroq bo'lgan kam holatlaridan biri: bizga aniq tur kerak.

Vazifa 6: Imkoniyat tekshiruvchi

imkoniyatlar(obyekt) funksiyasini yozing. Obyekt nimalar qila olishini aytsin:

python
imkoniyatlar([1, 2, 3])
text
✅ Iteratsiya qilinadi
✅ Uzunligi bor
✅ Indekslanadi
✅ O'zgartiriladi
❌ Chaqiriladi
❌ Xeshlanadi

Maslahat: __iter__, __len__, __getitem__, __setitem__, __call__, __hash__.

Vazifa 7: O'ylash

Quyidagi ikki funksiyadan qaysi biri yaxshiroq va nega?

python
# A
def qayta_ishla(malumot):
    if not isinstance(malumot, list):
        raise TypeError("Ro'yxat kerak")
    return [x * 2 for x in malumot]

# B
def qayta_ishla(malumot):
    return [x * 2 for x in malumot]
Javob

B yaxshiroq.

Sabablari:

  1. Moslashuvchan — juftlik, to'plam, generator, dict.values(), o'z sinfingiz bilan ishlaydi
  2. Xato baribir chiqadi — iteratsiya qilinmaydigan narsa berilsa TypeError avtomatik ko'tariladi
  3. Kamroq kod — o'qish oson
  4. Test qilish oson — soxta obyekt berish mumkin

A versiyasi hech qanday foyda bermay, sun'iy cheklov qo'yadi. Bu — o'rdak turlashi falsafasiga zid (2.3-bo'lim).

Istisno: agar funksiya aynan ro'yxatni o'zgartirsa (.append() chaqirsa), unda tekshirish o'rinli bo'lishi mumkin.

Nimani mustahkamlaydi: 2.2, 2.3, 2.4, 2.5, 2.6, 2.8-bo'limlar.


Xulosa

Bu darsda turlarni bilish va ular haqida to'g'ri o'ylashni o'rgandik.

Eng muhim uch fikr:

  1. isinstance() ishlating, type() == emas. U meros bilan to'g'ri ishlaydi. Lekin bool ni int dan oldin, str ni Sequence dan oldin tekshirishni unutmang.

  2. O'rdak turlashi — Python usuli. "Bu qanday tur?" o'rniga "Bu nima qila oladi?" deb so'rang. Tur tekshirish ko'pincha sun'iy cheklov qo'yadi va foyda bermaydi.

  3. EAFP ni afzal ko'ring. try/except — Python idiomasi. U qisqaroq, ko'pincha tezroq va poyga shartlaridan xoli.

Keyingi darsda turlarni aylantirish ni o'rganamiz: int(), float(), str(), list() va boshqalar. Qaysi aylantirish xavfsiz, qaysi biri ma'lumot yo'qotadi va nega int("3.14") xato beradi.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
3.8-dars: type() va turlarni bilish — IlmHamroh