Shpargalka: tez ma'lumotnoma
Bu bob o'qish uchun emas, qarash uchun.
Yangi loyiha boshlash
bash7 qator
mkdir loyiha && cd loyiha python3 -m venv .venv .venv/bin/python3 -m pip install -U pip mkdir -p src/paket tests touch src/paket/__init__.py # pyproject.toml yozing (pastda), keyin: .venv/bin/python3 -m pip install -e ".[dev]"
pyproject.toml namunasi
python29 qator
[project]
name = "paket"
version = "0.1.0"
description = "Bir qatorlik tavsif"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
dependencies = []
[project.optional-dependencies]
dev = ["pytest>=8", "pytest-cov>=5", "mypy>=1.8", "ruff>=0.5"]
[project.scripts]
paket = "paket.cli:main"
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q --strict-markers"
[tool.coverage.run]
source = ["paket"]
[tool.coverage.report]
show_missing = true
exclude_lines = ["pragma: no cover", "if __name__ == .__main__.:"]
Loyiha tuzilishi
python18 qator
loyiha/
├── pyproject.toml
├── ruff.toml
├── mypy.ini
├── README.md
├── .gitignore
├── .env.namuna
├── src/paket/
│ ├── __init__.py # ommaviy yuz: importlar + __version__
│ ├── __main__.py # python3 -m paket
│ ├── cli.py # argparse
│ ├── modellar.py # dataclass, Enum
│ ├── sozlama.py # muhit o'zgaruvchilari
│ ├── xatolar.py # istisno oilasi
│ └── ... # har modul bitta ish
└── tests/
├── conftest.py # umumiy fixture lar (__init__.py YO'Q)
└── test_*.py
Kundalik buyruqlar
python9 qator
.venv/bin/python3 -m pytest # testlar .venv/bin/python3 -m pytest --lf # faqat oxirgi yiqilganlar .venv/bin/python3 -m pytest -k "sana" # nom bo'yicha .venv/bin/python3 -m pytest --cov=paket --cov-report=term-missing python3 -m mypy # turlar ruff check src tests # linter ruff check --fix src tests # avtomatik tuzatish ruff format src tests # formatlash ./tekshir.sh # hammasi
Turlar
python8 qator
def f(a: int, b: str = "x") -> bool: ... xs: list[int] = [] d: dict[str, list[int]] = {} t: tuple[int, str] = (1, "a") ixtiyoriy: int | None = None # 3.10+; eskisi Optional[int] from collections.abc import Callable, Iterable, Sequence fn: Callable[[int, str], bool] from typing import Any, TypeVar, Protocol
| Kirish turi | Ishlating |
|---|---|
| Faqat aylanib chiqiladi | Iterable[T] |
Indeks va len kerak |
Sequence[T] |
| O'zgartiriladi | list[T] |
| Qaytish turi | Har doim aniq: list[T], dict[K, V] |
dataclass
python13 qator
from dataclasses import dataclass, field, replace @dataclass(frozen=True, slots=True) class Model: ism: str baho: int = 0 teglar: list[str] = field(default_factory=list) # [] EMAS! @property def katta(self) -> bool: return self.baho > 90 yangi = replace(eski, baho=95) # frozen da o'zgartirish
frozen=True — tasodifiy o'zgarishdan himoya. slots=True — imlo xatosini ushlaydi.
Python 3.10 da ikkalasi birga tushunarsiz TypeError beradi (3.11 da tuzatilgan).
Istisnolar
python9 qator
class LoyihaXato(Exception): ... # ildiz class FaylXato(LoyihaXato): def __init__(self, yol: str, sabab: str) -> None: self.yol, self.sabab = yol, sabab # MA'LUMOT saqlang, faqat matn emas super().__init__(f"{yol}: {sabab}") raise Yangi(...) from e # sababni saqlash raise Yangi(...) from None # sababni yashirish
| Qilmang | Qiling |
|---|---|
except: |
except AniqXato: |
except Exception: pass |
Jurnalga yozing yoki qayta oting |
return -1 xato o'rniga |
raise |
20 qatorli try |
Qisqa try, har tekshiruv alohida |
Testlar
python28 qator
import pytest @pytest.mark.parametrize("kirish, kutilgan", [("85", 85), ("0", 0)]) def test_holat(kirish, kutilgan): assert f(kirish) == kutilgan def test_xato(): with pytest.raises(ValueError, match="son emas"): f("abc") @pytest.fixture def malumot(): return [1, 2, 3] def test_fayl(tmp_path): # har testga yangi papka (tmp_path / "a.txt").write_text("x", encoding="utf-8") def test_muhit(monkeypatch): # vaqtincha o'zgartirish monkeypatch.setenv("KALIT", "qiymat") def test_chiqish(capsys): # stdout/stderr ni ushlash print("salom") assert "salom" in capsys.readouterr().out def test_jurnal(caplog): # jurnalni ushlash with caplog.at_level(logging.WARNING): ... assert "ogohlantirish" in caplog.text
| Fixture | Beradi |
|---|---|
tmp_path |
Yangi bo'sh papka (Path) |
capsys |
stdout / stderr matni |
caplog |
Jurnal xabarlari |
monkeypatch |
Vaqtincha setenv, setattr, chdir |
Jurnal
python12 qator
import logging log = logging.getLogger(__name__) # HAR modulda log.debug("tafsilot: %s", x) # f-string emas, %s log.info("ish tugadi: %d qator", n) log.warning("%d qator rad etildi", k) log.error("bajarilmadi: %s", e) log.exception("kutilmagan xato") # faqat except ichida, iz bilan # FAQAT dastur sozlaydi, kutubxona emas: logging.basicConfig(level=logging.INFO, stream=sys.stderr, format="%(asctime)s %(levelname)-8s %(name)s: %(message)s")
Fayllar
python20 qator
from pathlib import Path p = Path("malumot") / "2026" / "f.csv" p.parent.mkdir(parents=True, exist_ok=True) matn = p.read_text(encoding="utf-8") # encoding HAR DOIM p.write_text(matn, encoding="utf-8") p.with_suffix(".json") list(p.parent.glob("*.csv")) # rglob — ichkilari bilan import json json.dumps(d, ensure_ascii=False, indent=2) # o'zbekcha harflar uchun json.dumps(d, default=str) # date, Decimal uchun import csv with p.open("w", encoding="utf-8", newline="") as f: # newline="" MUHIM w = csv.DictWriter(f, fieldnames=[...]) w.writeheader(); w.writerows(qatorlar) import sqlite3 con.execute("SELECT * FROM t WHERE ism = ?", (ism,)) # ? — injection dan himoya
Konfiguratsiya
python12 qator
import os def son(nom, sukut): xom = os.environ.get(nom) return sukut if not xom else int(xom) # int() xato bersa — ushlang def mantiqiy(nom, sukut): xom = os.environ.get(nom, "").lower() if not xom: return sukut if xom in {"1","true","ha","on"}: return True if xom in {"0","false","yo'q","off"}: return False raise ValueError(f"{nom}: mantiqiy qiymat kutilgan")
bool("false") → True. Hech qachon bool(os.environ.get(...)) yozmang.
Parallellik
python12 qator
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed with ThreadPoolExecutor(max_workers=8) as p: # I/O uchun natijalar = list(p.map(f, elementlar)) with ProcessPoolExecutor(max_workers=4) as p: # CPU uchun natijalar = list(p.map(f, elementlar)) # f import qilinadigan modulda bo'lsin! with ThreadPoolExecutor() as p: kelajaklar = {p.submit(f, x): x for x in elementlar} for k in as_completed(kelajaklar): natija = k.result()
| Ish | Vosita |
|---|---|
| Fayl, tarmoq, baza (I/O) | ThreadPoolExecutor |
| Hisob (CPU) | ProcessPoolExecutor |
| Minglab ulanish | asyncio |
| Kichik ish | Oddiy sikl — parallellik qimmat |
asyncio da time.sleep emas, await asyncio.sleep.
HTTP
python7 qator
import requests j = requests.get(url, timeout=5) # timeout MAJBURIY j.raise_for_status() malumot = j.json() s = requests.Session() # ko'p so'rovda tezroq
Qayta urinish: faqat 408, 429, 5xx da. 404, 401 — darhol to'xtang. Kutish: eksponensial + jitter.
Tezlik
python12 qator
import time, timeit, cProfile, pstats, tracemalloc from functools import lru_cache t0 = time.perf_counter() # time.time() EMAS timeit.timeit(lambda: f(), number=100) cProfile.run("f()", sort="tottime") # tottime — nishon, cumtime — yo'nalish @lru_cache(maxsize=1024) def qimmat(x): ... tracemalloc.start(); f(); cho_qqi = tracemalloc.get_traced_memory()[1]
| Muammo | Yechim |
|---|---|
x in ro'yxat sekin |
set yoki dict ishlating |
| Bir hisob takrorlanadi | lru_cache |
| Katta fayl xotiraga sig'maydi | Generator, qator-qator |
| Qayerda sekin — noma'lum | cProfile, taxmin qilmang |
Eng ko'p uchraydigan xatolar
| Xato | Oqibati | To'g'risi |
|---|---|---|
def f(x=[]) |
Ro'yxat chaqiruvlar orasida saqlanadi | x=None, ichida [] |
== None |
__eq__ yolg'on gapirishi mumkin |
is None |
except: |
Ctrl+C ham yutiladi |
except AniqXato: |
open(yol) |
Platformaga bog'liq kodlash | encoding="utf-8" |
requests.get(url) |
Cheksiz osilish | timeout=5 |
bool("false") |
True |
Qo'lda tahlil qiling |
| f-string jurnалда | Har doim hisoblanadi | log.debug("%s", x) |
csv + newline=None |
Windows da bo'sh qatorlar | newline="" |
json.py fayl nomi |
Standart kutubxonani berkitadi | Boshqa nom |
tests/__init__.py |
pytest import muammosi | Yaratmang |
| SQL da f-string | SQL injection | ? parametri |
time.sleep async da |
Butun tsikl bloklanadi | await asyncio.sleep |
Global SOZLAMA |
Testlar bir-biriga ta'sir qiladi | Argument sifatida uzating |
sys.exit() main() ichida |
Testdan chaqirib bo'lmaydi | return kod |
Qaytish kodlari
| Kod | Ma'nosi |
|---|---|
| 0 | Muvaffaqiyat |
| 1 | Umumiy xato |
| 2 | Noto'g'ri ishlatish (argument, sozlama) |
| 130 | Ctrl+C |
Tekshiruv ro'yxati: yakunlashdan oldin
- [ ]
./tekshir.shtoza o'tadi (format, linter, turlar, testlar) - [ ] Qamrov maqbul (60%+);
Missingqatorlari ko'rib chiqilgan - [ ]
README.mdda o'rnatish va uchta ishlatish misoli bor - [ ]
.env.gitignoreda;.env.namunayozilgan - [ ] Kodda parol, token, kalit yo'q (
git log -p | grep -i "key\|token\|parol") - [ ] Xato xabarlari foydalanuvchi uchun tushunarli,
stderrga chiqadi - [ ] Qaytish kodlari to'g'ri
- [ ]
main(argv)testdan chaqirilishi mumkin - [ ] Har tashqi so'rovda
timeoutbor - [ ] Har
open()daencodingbor - [ ] Eng katta fayl 400 qatordan kam
- [ ] Yechilmagan cheklovlar
READMEyoki izohda yozilgan
Kitobdagi o'lchovlar
| Bob | O'lchangan natija |
|---|---|
| 1 | Skript 9 qator, ajratilgan variant 50 — lekin u qaysi qator nega rad etilganini aytadi |
| 2 | Bitta requests bilan birga 4 ta bog'liqlik keldi |
| 4 | slots=True imlo xatosini ushladi; slots siz u jim o'tdi |
| 5 | --strict siz mypy turlanmagan kodni umuman tekshirmaydi |
| 7 | 100% qamrov hech narsani tekshirmaydigan test bilan ham olinadi |
| 9 | isEnabledFor bilan o'chiq DEBUG deyarli 0 ms |
| 10 | latin-1 xato bermaydi, lekin matnni buzadi |
| 13 | CPU ishida thread lar foyda bermadi, jarayonlar berdi |
| 14 | Generator ro'yxatdan yuzlab barobar kam xotira oldi |
| 16 | B006 va E711 — linter topgan haqiqiy xatolar |
Kitobning asosiy g'oyasi: har bir tanlovni o'lchang va tekshiring. "Ishlayotganga o'xshaydi" — bu dalil emas.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.