Type hints — list[int], Optional, Union, dict[str, int], TypeVar
Muammodan boshlaylik
Hamkasbingiz yozgan funksiya:
def hisobla(m, c, d):
...
m nima — son? ro'yxat? dictionary? c — foiz yoki summa? Natija qanday? Javob olish uchun funksiya ichini o'qish kerak. Va xato faqat ishga tushirganda chiqadi:
hisobla("100000", 10, None)
# TypeError: can't multiply sequence by non-int of type 'float' — 200-qatorda, ishlab chiqarishda
Python dinamik tipli til — turlarni yozish shart emas. Lekin katta loyihada turlar hujjat va xatolarni erta topish vositasi.
Type hints nima?
Type hints — o'zgaruvchilar, parametrlar va qaytish qiymatining turini ko'rsatuvchi izohlar:
def chegirmali_narx(narx: int, foiz: float = 0.0) -> float:
return narx * (1 - foiz / 100)
narx: int— parametr turi-> float— qaytish qiymati turi- Funksiya imzosidan hamma narsa ko'rinadi
[!INFO] Type hints dastur ishlashiga ta'sir qilmaydi — Python ularni tekshirmaydi:
chegirmali_narx("abc")baribir ishga tushadi (va xato beradi). Turlarni tekshiradi: muharrir (VS Code, PyCharm — qizil chiziq va avtomatik to'ldirish) va statik tahlil vositalari (mypy,pyright) — kodni ishga tushirmasdan.
Hayotiy o'xshatma
Elektr rozetkalari va vilkalarda belgilar: "220V", "16A". Ular tokning o'zini o'zgartirmaydi — lekin noto'g'ri qurilmani ulamaslikka yordam beradi. Elektrik (mypy) esa ulashdan oldin hamma narsani tekshirib chiqadi.
Oddiy turlar
ism: str = "Lola"
yosh: int = 20
reyting: float = 4.8
faol: bool = True
def salomlash(ism: str) -> str:
return f"Salom, {ism}"
def log_yoz(xabar: str) -> None: # hech narsa qaytarmaydi
print(xabar)
Kolleksiyalar
Python 3.9+ da o'rnatilgan turlar bilan:
baholar: list[int] = [5, 4, 5]
narxlar: dict[str, int] = {"olma": 15000}
noyob: set[str] = {"a", "b"}
nuqta: tuple[float, float] = (41.29, 69.24)
qiymatlar: tuple[int, ...] = (1, 2, 3, 4) # istalgan uzunlik
def ortacha(sonlar: list[float]) -> float:
return sum(sonlar) / len(sonlar)
def guruhla(talabalar: list[dict[str, str]]) -> dict[str, list[str]]:
...
[!INFO] Eski kodda (Python 3.8 va undan oldin)
from typing import List, Dict, TuplevaList[int]ko'rinishini uchratasiz. Hozir kichik harflilist[int],dict[str, int]— tavsiya etilgan.
Optional va Union
Bir nechta tur — |
def id_formatla(id_: int | str) -> str:
return str(id_).zfill(6)
None bo'lishi mumkin
def foydalanuvchi_top(email: str) -> dict | None:
for u in foydalanuvchilar:
if u["email"] == email:
return u
return None
def salom(ism: str | None = None) -> str:
return f"Salom, {ism or 'mehmon'}"
X | None — "X yoki None". Eski yozuv: Optional[X] yoki Union[X, None] (from typing import Optional, Union).
Natija | None bo'lsa, mypy uni ishlatishdan oldin tekshirishni talab qiladi:
u = foydalanuvchi_top("lola@mail.uz")
print(u["ism"]) # ❌ mypy: Value of type "dict | None" is not indexable
if u is not None:
print(u["ism"]) # ✅
Bu — NoneType xatolarining ('NoneType' object is not subscriptable) katta qismini kod ishga tushmasdan oldin topadi.
Boshqa foydali turlar
from typing import Any, Literal, Callable, TypedDict
from collections.abc import Iterable, Iterator
def chop_et(x: Any) -> None: ... # istalgan tur (tekshiruvni o'chiradi)
def tartibla(yonalish: Literal["osish", "kamayish"]) -> None: ... # faqat shu qiymatlar
def qayta_urin(f: Callable[[int], str], marta: int) -> str: ... # funksiya turi
def jami(sonlar: Iterable[int]) -> int: # list, tuple, set, generator — hammasi
return sum(sonlar)
def sanash(n: int) -> Iterator[int]: # generator (45-dars)
yield from range(n)
TypedDict — tuzilmali dictionary
from typing import TypedDict, NotRequired
class Talaba(TypedDict):
ism: str
yosh: int
email: NotRequired[str]
t: Talaba = {"ism": "Lola", "yosh": 20}
t["yoshi"] # ❌ mypy: TypedDict "Talaba" has no key "yoshi"
JSON API javoblari kabi dictionary lar uchun — kalitlar va turlar tekshiriladi.
O'z klasslaringiz
class BankHisobi:
def __init__(self, egasi: str, balans: int = 0) -> None:
self.egasi = egasi
self.balans = balans
def otkaz(self, boshqa: "BankHisobi", summa: int) -> bool:
...
def eng_boy(hisoblar: list[BankHisobi]) -> BankHisobi:
return max(hisoblar, key=lambda h: h.balans)
Klass o'z ichida o'ziga murojaat qilsa — qo'shtirnoqda ("BankHisobi") yoki faylning boshida from __future__ import annotations. Python 3.11+ da — typing.Self.
TypeVar va generic lar
"Ro'yxatning birinchi elementini qaytaradi" — qanday tur?
def birinchi(royxat: list) -> object: # ❌ tur ma'lumoti yo'qoladi
return royxat[0]
TypeVar — "kirgan tur bilan bir xil tur":
from typing import TypeVar
T = TypeVar("T")
def birinchi(royxat: list[T]) -> T:
return royxat[0]
a = birinchi([1, 2, 3]) # mypy biladi: a — int
b = birinchi(["x", "y"]) # b — str
Python 3.12+ da qisqaroq sintaksis:
def birinchi[T](royxat: list[T]) -> T:
return royxat[0]
mypy — turlarni tekshirish
pip install mypy
mypy dastur.py
# dastur.py
def chegirmali_narx(narx: int, foiz: float) -> float:
return narx * (1 - foiz / 100)
chegirmali_narx("100000", 10)
dastur.py:4: error: Argument 1 to "chegirmali_narx" has incompatible type "str"; expected "int"
Found 1 error in 1 file (checked 1 source file)
Xato — kod ishga tushirilmasdan, CI da (Express kursi, 67-dars kabi) avtomatik topiladi.
[!TIP] Turlarni bosqichma-bosqich qo'shing: avval funksiya imzolari (parametrlar va qaytish qiymati) — eng ko'p foyda shundan. Lokal o'zgaruvchilarga odatda yozish shart emas — tur avtomatik aniqlanadi (
x = 5—int). Pydantic, FastAPI kabi kutubxonalar esa type hints dan ishlash paytida validatsiya uchun ham foydalanadi.
Tez-tez uchraydigan xatolar
Type hints ni runtime tekshiruv deb o'ylash:
def f(x: int): return x * 2
f("ab") # "abab" — Python hech narsa demaydi; mypy esa xato topadi
Standart qiymat None, tur esa None siz:
def f(ism: str = None): ... # ❌ mypy xatosi
def f(ism: str | None = None): ... # ✅
list ni element turisiz — list (nima ro'yxati?) o'rniga list[int].
Xulosa
Type hints — kodni o'z-o'zidan hujjatlashtiruvchi va xatolarni erta topishga yordam beruvchi izohlar.
Eslab qoling:
x: int,def f(a: str) -> bool:,-> Nonelist[int],dict[str, int],tuple[float, float],set[str]int | str,X | None(=Optional[X]); None ni tekshirishga majbur qiladiLiteral,Callable,Iterable,Iterator,TypedDict,AnyTypeVar/def f[T](...)— generic funksiyalar- Python tekshirmaydi —
mypy/pyrightva muharrir tekshiradi
Keyingi dars
49-dars: Dataclasses — @dataclass, field, frozen, __post_init__