20. Professional Python dasturlash va loyiha yaratish

Python'da asosiy sintaksisni o‘rganish dasturchi bo‘lishning boshlanishidir.

Professional dastur yaratish uchun esa faqat:

o‘zgaruvchilar
funksiyalar
sinflar
modullar

ni bilish yetarli emas.

Katta loyihalarda kodni:

tartibli
o‘qilishi oson
test qilinadigan
kengaytiriladigan
xavfsiz
boshqarish oson

qilib yozish kerak.

Bu bobda professional Python loyihasini yaratish va boshqarish bilan bog‘liq asosiy tushunchalarni o‘rganamiz.


Loyiha strukturasi

Kichik dastur bitta faylda bo‘lishi mumkin:

dastur.py

Ammo loyiha kattalashgani sari kodni bir nechta fayl va papkalarga ajratish kerak.

Masalan:

softromeda/
├── pyproject.toml
├── README.md
├── .gitignore
├── talablar.txt
├── manba/
│   └── softromeda/
│       ├── __init__.py
│       ├── asosiy.py
│       ├── sozlamalar.py
│       ├── xizmatlar.py
│       └── modellar.py
└── testlar/
    ├── __init__.py
    └── test_xizmatlar.py

Bu struktura kodni tartibli saqlashga yordam beradi.


Modullarga ajratish

Bitta katta fayl o‘rniga vazifalarni alohida modullarga ajratish yaxshi amaliyot.

Masalan:

asosiy.py

dastur ishga tushishini boshqaradi.

sozlamalar.py

sozlamalarni boshqaradi.

xizmatlar.py

biznes mantiqni bajaradi.

modellar.py

ma’lumotlar modellarini saqlaydi.


__init__.py

Python paketlarida:

__init__.py

fayli ishlatilishi mumkin.

Masalan:

softromeda/
└── __init__.py

Bu fayl paketni tashkil qilishda foydali.

U bo‘sh ham bo‘lishi mumkin:

yoki paket uchun boshlang‘ich sozlamalarni o‘z ichiga olishi mumkin.


Virtual muhit

Har bir loyiha uchun alohida Python muhitidan foydalanish yaxshi amaliyot.

Buning uchun:

python -m venv .venv

buyrug‘idan foydalanish mumkin.

Bu:

.venv

nomli virtual muhit yaratadi.


Virtual muhitni faollashtirish

Windows:

.venv\Scripts\activate

Linux yoki macOS:

source .venv/bin/activate

Faollashtirilgandan keyin loyiha o‘zining alohida Python paketlariga ega bo‘ladi.


Virtual muhit nima uchun kerak?

Tasavvur qiling:

Loyiha A
    requests 2.x

Loyiha B
    requests 3.x

Agar barcha paketlar tizim bo‘yicha o‘rnatilsa, versiyalar bir-biriga xalaqit berishi mumkin.

Virtual muhit yordamida:

Loyiha A → o‘z muhiti
Loyiha B → o‘z muhiti

bo‘ladi.


pip

Python paketlarini o‘rnatish uchun ko‘pincha:

pip

ishlatiladi.

Masalan:

pip install requests

Bu requests paketini o‘rnatadi.


Paketni yangilash

pip install --upgrade requests

Bu paketning yangiroq versiyasini o‘rnatishga harakat qiladi.


Paketni o‘chirish

pip uninstall requests

O‘rnatilgan paketlarni ko‘rish

pip list

Bu virtual muhitda o‘rnatilgan paketlarni ko‘rsatadi.


Talablar fayli

Loyiha qaysi paketlardan foydalanishini saqlash uchun talablar fayli ishlatilishi mumkin.

Masalan:

talablar.txt

Ichida:

requests
aiohttp

bo‘lishi mumkin.

Keyin:

pip install -r talablar.txt

orqali barcha paketlarni o‘rnatish mumkin.


Paket versiyalarini belgilash

Professional loyihada paket versiyalarini aniq belgilash foydali.

Masalan:

requests==2.32.4
aiohttp==3.12.15

Bu loyiha qaysi versiyalarga tayanishini aniq ko‘rsatadi.


requirements.txt

Python loyihalarida eng ko‘p uchraydigan nom:

requirements.txt

Masalan:

requests==2.32.4
aiohttp==3.12.15

O‘rnatish:

pip install -r requirements.txt

pyproject.toml

Zamonaviy Python loyihalarida:

pyproject.toml

muhim konfiguratsiya fayliga aylangan.

Masalan:

[project]
name = "softromeda"
version = "1.0.0"
description = "Softromeda Python loyihasi"
requires-python = ">=3.12"

dependencies = [
    "requests",
    "aiohttp"
]

Bu fayl loyiha haqida muhim ma’lumotlarni saqlashi mumkin.


Type hint

Professional Python kodida type hintlardan foydalanish kodni tushunarli qiladi.

Masalan:

def qo'shish(
    birinchi: int,
    ikkinchi: int
) -> int:

    return birinchi + ikkinchi

Bu yerda:

birinchi → int
ikkinchi → int
natija → int

ekanligi ko‘rsatilgan.


str

Matn uchun:

def salom_berish(
    ism: str
) -> str:

    return f"Salom, {ism}!"

list

Ro‘yxat uchun:

def sonlarni_qaytarish() -> list[int]:

    return [
        1,
        2,
        3
    ]

dict

Lug‘at uchun:

def foydalanuvchi() -> dict[str, str]:

    return {
        "ism": "Ali",
        "shahar": "Toshkent"
    }

Optional

Qiymat mavjud bo‘lishi yoki None bo‘lishi mumkin.

def foydalanuvchini_topish(
    foydalanuvchi_id: int
) -> dict[str, str] | None:

    if foydalanuvchi_id == 1:

        return {
            "ism": "Ali"
        }

    return None

Type hintning foydasi

Type hint:

kodni tushunarli qiladi
xatolarni oldindan aniqlashga yordam beradi
IDE yordamlarini yaxshilaydi
funksiya bilan ishlashni osonlashtiradi

Lekin type hint Python'da avtomatik ravishda barcha qiymatlarni tekshiradigan mexanizm emas.

U asosan:

dasturchi
IDE
statik tahlil vositalari

uchun ma’lumot beradi.


dataclass

Ma’lumotlarni saqlaydigan oddiy sinflar uchun:

from dataclasses import dataclass


@dataclass
class Foydalanuvchi:

    ism: str
    yosh: int

Foydalanish:

foydalanuvchi = Foydalanuvchi(
    ism="Ali",
    yosh=25
)

print(
    foydalanuvchi
)

Logging

Professional dasturda hamma narsani:

print()

bilan chiqarish yaxshi amaliyot emas.

Buning o‘rniga:

logging

modulidan foydalanish mumkin.

import logging

logging.basicConfig(
    level=logging.INFO
)

jurnal = logging.getLogger(
    "softromeda"
)

jurnal.info(
    "Dastur ishga tushdi."
)

Logging darajalari

Eng ko‘p ishlatiladigan darajalar:

DEBUG
INFO
WARNING
ERROR
CRITICAL

Masalan:

jurnal.debug(
    "Texnik ma'lumot."
)

jurnal.info(
    "Amal muvaffaqiyatli bajarildi."
)

jurnal.warning(
    "Ogohlantirish."
)

jurnal.error(
    "Xatolik yuz berdi."
)

jurnal.critical(
    "Jiddiy xatolik."
)

Logging va print

print():

print(
    "Dastur ishga tushdi."
)

oddiy chiqish uchun foydali.

logging esa:

jurnal.info(
    "Dastur ishga tushdi."
)

kabi professional dasturlarda yaxshiroq.

Chunki loglarni:

daraja
vaqt
fayl
konsol

bo‘yicha boshqarish mumkin.


Logging faylga yozish

Masalan:

import logging


logging.basicConfig(
    filename="softromeda.log",
    level=logging.INFO
)

jurnal = logging.getLogger(
    "softromeda"
)

jurnal.info(
    "Dastur ishga tushdi."
)

Log ma’lumotlari:

softromeda.log

fayliga yozilishi mumkin.


Test yozish

Professional kod test qilinishi kerak.

Python'da standart test vositalaridan biri:

unittest

hisoblanadi.

Masalan:

import unittest


def qo'shish(
    birinchi: int,
    ikkinchi: int
) -> int:

    return birinchi + ikkinchi


class Qo'shishTesti(
    unittest.TestCase
):

    def test_qo'shish(self):

        natija = qo'shish(
            2,
            3
        )

        self.assertEqual(
            natija,
            5
        )


if __name__ == "__main__":

    unittest.main()

Test nima?

Test dasturdagi ma’lum bir xatti-harakat to‘g‘ri ishlayotganini tekshiradi.

Masalan:

2 + 3 = 5

degan qoidani test qilish mumkin.

Agar keyinchalik kod o‘zgartirilsa va:

2 + 3

5 o‘rniga boshqa qiymat qaytarsa, test buni aniqlaydi.


Test strukturasi

Professional loyihada testlarni alohida papkada saqlash mumkin:

softromeda/
├── manba/
│   └── softromeda/
│       ├── asosiy.py
│       └── xizmatlar.py
└── testlar/
    ├── test_xizmatlar.py
    └── test_asosiy.py

Kod sifati

Yaxshi kod:

o‘qilishi oson
oddiy
mantiqan ajratilgan
nomlari tushunarli
keraksiz takrorlanishsiz
test qilinadigan

bo‘lishi kerak.

Masalan, yomon:

def h(a, b):
    return a * b

Agar vazifa mahsulot narxi va miqdorini hisoblash bo‘lsa:

def umumiy_narx(
    narx: float,
    miqdor: int
) -> float:

    return narx * miqdor

ancha tushunarli.


Nom berish

Python'da odatda:

o‘zgaruvchi_va_funksiya → snake_case
sinf → PascalCase
doimiy qiymat → KATTA_HARFLAR

ishlatiladi.

Masalan:

foydalanuvchi_nomi = "Ali"

def foydalanuvchini_olish():
    ...


class Foydalanuvchi:
    ...


MAKSIMAL_YOSH = 120

Kichik funksiyalar

Juda katta funksiyalarni kichik qismlarga ajratish foydali.

Masalan, bitta katta funksiya:

def dastur():

    # ma'lumot olish
    # tekshirish
    # hisoblash
    # saqlash
    # chiqarish
    ...

o‘rniga:

def ma'lumot_olish():
    ...


def ma'lumotni_tekshirish():
    ...


def hisoblash():
    ...


def saqlash():
    ...


def natijani_chiqarish():
    ...

kabi ajratish mumkin.


DRY

DRY:

Don't Repeat Yourself

ya’ni:

O‘zingizni takrorlamang.

Bir xil kodni ko‘p marta yozish o‘rniga umumiy funksiya yaratish mumkin.

Yomon:

print(
    "Salom, Ali!"
)

print(
    "Salom, Vali!"
)

print(
    "Salom, Hasan!"
)

Yaxshiroq:

def salom_berish(
    ism: str
):

    print(
        f"Salom, {ism}!"
    )


salom_berish("Ali")

salom_berish("Vali")

salom_berish("Hasan")

KISS

KISS tamoyili:

Keep It Simple

Mazmuni:

Muammoni keragidan ortiq murakkablashtirmang.

Agar oddiy funksiya yetarli bo‘lsa, faqat murakkab ko‘rinishi uchun qo‘shimcha sinflar va qatlamlar yaratish shart emas.


Istisnolarni boshqarish

Professional kodda xatolarni nazorat qilish kerak.

def sonni_bolish(
    birinchi: float,
    ikkinchi: float
) -> float:

    if ikkinchi == 0:

        raise ValueError(
            "Ikkinchi son nol bo‘lishi mumkin emas."
        )

    return birinchi / ikkinchi

Keyin:

try:

    natija = sonni_bolish(
        10,
        0
    )

except ValueError as xato:

    print(
        f"Xatolik: {xato}"
    )

Git

Professional dasturchilar ko‘pincha:

Git

versiya boshqaruv tizimidan foydalanadi.

Git yordamida koddagi o‘zgarishlarni kuzatish mumkin.

Masalan:

git init

yangi Git omborini yaratadi.


Git holatini ko‘rish

git status

Bu o‘zgargan fayllarni ko‘rsatadi.


Git'ga fayl qo‘shish

git add .

Bu o‘zgarishlarni keyingi commit uchun tayyorlaydi.


Commit

git commit -m "Boshlang'ich loyiha"

Commit loyihadagi ma’lum holatni saqlaydi.


Git tarixini ko‘rish

git log

Bu commitlar tarixini ko‘rsatadi.


.gitignore

Ba’zi fayllarni Git'ga yubormaslik kerak.

Masalan:

.venv/
__pycache__/
*.pyc
.env

Buning uchun:

.gitignore

fayli yaratiladi.

Masalan:

.venv/
__pycache__/
*.pyc
.env

Maxfiy ma’lumotlar, virtual muhit va vaqtinchalik fayllarni omborga qo‘shmaslik muhim.


Muhit o‘zgaruvchilari

Maxfiy ma’lumotlarni:

api_kalit = "maxfiy_kalit"

ko‘rinishida kodga yozish yaxshi emas.

Buning o‘rniga muhit o‘zgaruvchisidan foydalanish mumkin:

import os


api_kalit = os.getenv(
    "SOFTROMEDA_API_KALITI"
)

.env

Lokal ishlab chiqishda .env fayli ishlatilishi mumkin.

Masalan:

SOFTROMEDA_API_KALITI=maxfiy_kalit

Ammo:

.env

odatda Git'ga yuborilmasligi kerak.

.gitignore:

.env

README

Har bir yaxshi loyihada:

README.md

fayli bo‘lishi foydali.

Unda:

loyiha nima?
qanday o‘rnatiladi?
qanday ishga tushiriladi?
qanday foydalaniladi?
qanday test qilinadi?

kabi ma’lumotlar yoziladi.


Professional loyiha namunasi

Softromeda uchun quyidagi struktura yaxshi boshlanish bo‘lishi mumkin:

softromeda/
├── .gitignore
├── README.md
├── pyproject.toml
├── requirements.txt
├── .env
├── manba/
│   └── softromeda/
│       ├── __init__.py
│       ├── asosiy.py
│       ├── sozlamalar.py
│       ├── modellar.py
│       ├── xizmatlar.py
│       └── api.py
└── testlar/
    ├── __init__.py
    ├── test_xizmatlar.py
    └── test_api.py

Yakuniy amaliy loyiha

Endi bobdagi bilimlardan foydalanib to‘liqroq loyiha yaratamiz.

Loyiha:

Softromeda vazifalar boshqaruv dasturi

bo‘ladi.

Dastur quyidagi imkoniyatlarga ega:

vazifa yaratish
vazifalarni ko‘rish
vazifani bajarilgan deb belgilash
vazifani o‘chirish
ma’lumotlarni saqlash
log yuritish
testlar
Git versiya boshqaruvi

Loyiha modeli

from dataclasses import dataclass


@dataclass
class Vazifa:

    identifikator: int
    nom: str
    bajarilgan: bool = False

Bu yerda har bir vazifa:

identifikator
nom
bajarilgan

xususiyatlariga ega.


Vazifalar xizmati

from dataclasses import dataclass


@dataclass
class Vazifa:

    identifikator: int
    nom: str
    bajarilgan: bool = False


class VazifalarXizmati:

    def __init__(self):

        self.vazifalar: list[Vazifa] = []

        self.keyingi_identifikator = 1

    def yaratish(
        self,
        nom: str
    ) -> Vazifa:

        vazifa = Vazifa(
            identifikator=self.keyingi_identifikator,
            nom=nom
        )

        self.vazifalar.append(
            vazifa
        )

        self.keyingi_identifikator += 1

        return vazifa

    def barchasini_olish(
        self
    ) -> list[Vazifa]:

        return self.vazifalar

    def bajarilgan_deb_belgilash(
        self,
        identifikator: int
    ) -> bool:

        for vazifa in self.vazifalar:

            if (
                vazifa.identifikator
                == identifikator
            ):

                vazifa.bajarilgan = True

                return True

        return False

    def o'chirish(
        self,
        identifikator: int
    ) -> bool:

        for vazifa in self.vazifalar:

            if (
                vazifa.identifikator
                == identifikator
            ):

                self.vazifalar.remove(
                    vazifa
                )

                return True

        return False

Logging qo‘shish

import logging


logging.basicConfig(
    level=logging.INFO,
    format=(
        "%(asctime)s - "
        "%(levelname)s - "
        "%(message)s"
    )
)

jurnal = logging.getLogger(
    "softromeda"
)

Keyin xizmat ichida:

jurnal.info(
    f"Vazifa yaratildi: {nom}"
)

kabi yozuvlardan foydalanish mumkin.


Test

Vazifalar xizmatini test qilish:

import unittest


class VazifalarXizmatiTesti(
    unittest.TestCase
):

    def test_vazifa_yaratish(self):

        xizmat = VazifalarXizmati()

        vazifa = xizmat.yaratish(
            "Python o‘rganish"
        )

        self.assertEqual(
            vazifa.nom,
            "Python o‘rganish"
        )

        self.assertFalse(
            vazifa.bajarilgan
        )

    def test_vazifani_bajarish(
        self
    ):

        xizmat = VazifalarXizmati()

        vazifa = xizmat.yaratish(
            "Test yozish"
        )

        natija = (
            xizmat.bajarilgan_deb_belgilash(
                vazifa.identifikator
            )
        )

        self.assertTrue(
            natija
        )

        self.assertTrue(
            vazifa.bajarilgan
        )


if __name__ == "__main__":

    unittest.main()

Kodni ishga tushirish

Loyihada asosiy fayl:

asosiy.py

bo‘lishi mumkin.

Masalan:

from xizmatlar import (
    VazifalarXizmati
)


def asosiy():

    xizmat = VazifalarXizmati()

    xizmat.yaratish(
        "Python o‘rganish"
    )

    xizmat.yaratish(
        "API yaratish"
    )

    print(
        "=== Softromeda vazifalari ==="
    )

    for vazifa in (
        xizmat.barchasini_olish()
    ):

        holat = (
            "Bajarilgan"
            if vazifa.bajarilgan
            else "Bajarilmagan"
        )

        print(
            f"{vazifa.identifikator}. "
            f"{vazifa.nom} — {holat}"
        )


if __name__ == "__main__":

    asosiy()

Professional dasturchining ish jarayoni

Python loyihasini yaratishda quyidagi jarayon foydali:

1. Muammoni tushunish
        ↓
2. Loyiha strukturasini yaratish
        ↓
3. Virtual muhit yaratish
        ↓
4. Bog‘liqliklarni o‘rnatish
        ↓
5. Kod yozish
        ↓
6. Type hint qo‘shish
        ↓
7. Xatolarni boshqarish
        ↓
8. Logging qo‘shish
        ↓
9. Test yozish
        ↓
10. Git orqali versiyalarni saqlash
        ↓
11. Kodni tekshirish
        ↓
12. Hujjat yozish

Professional Python dasturchisi uchun asosiy ko‘nikmalar

Python'ni professional darajada ishlatish uchun quyidagilarni yaxshi bilish muhim:

Python sintaksisi
funksiyalar
obyektga yo‘naltirilgan dasturlash
modullar va paketlar
istisnolar
fayllar
JSON
API
ma’lumotlar bazasi
asinxron dasturlash
type hint
test
logging
Git
virtual muhit
paketlarni boshqarish
loyiha strukturasi

Kod yozish falsafasi

Professional dasturchi uchun:

kod ishlashi

yetarli emas.

Kod:

tushunarli
ishonchli
test qilinadigan
kengaytiriladigan
qo‘llab-quvvatlanadigan

bo‘lishi kerak.

Masalan, quyidagi kod ishlaydi:

a = 10
b = 20
c = a + b
print(c)

Ammo quyidagi kod maqsadni yaxshiroq bildiradi:

birinchi_son = 10

ikkinchi_son = 20

yig'indi = (
    birinchi_son
    + ikkinchi_son
)

print(
    f"Yig‘indi: {yig'indi}"
)

Kodning maqsadi o‘quvchiga aniqroq ko‘rinadi.


Bob xulosasi

Bu bobda professional Python dasturlash asoslarini o‘rgandik.

Loyiha strukturasi:

manba/
testlar/
README.md
pyproject.toml
requirements.txt
.gitignore

kabi fayl va papkalardan tashkil qilinishi mumkin.

Virtual muhit:

python -m venv .venv

orqali yaratiladi.

Paketlarni:

pip install

orqali boshqarish mumkin.

Type hint:

def qo'shish(
    a: int,
    b: int
) -> int:

kodni tushunarli qiladi.

Logging:

import logging

orqali professional log tizimini yaratishga yordam beradi.

Testlar:

import unittest

yordamida yozilishi mumkin.

Git esa:

kod tarixini
o‘zgarishlarni
versiyalarni

boshqarishga yordam beradi.

Eng muhimi, professional dasturchi faqat kod yozmaydi. U:

muammoni tahlil qiladi
loyihani rejalashtiradi
kodni tuzadi
test qiladi
xatolarni boshqaradi
hujjatlashtiradi
versiyalarni nazorat qiladi

va natijada boshqa dasturchilar ham tushunishi va davom ettirishi mumkin bo‘lgan sifatli dastur yaratadi.


Yakuniy amaliy topshiriq

Softromeda uchun to‘liq Python loyihasi yarating.

Loyiha quyidagilarga ega bo‘lsin:

loyiha strukturasi
virtual muhit
pyproject.toml
README.md
.gitignore
type hint
logging
testlar
Git
xatolarni boshqarish
JSON yoki ma’lumotlar bazasi
API bilan ishlash
asinxron operatsiyalar

Loyiha kamida quyidagi imkoniyatlarni bajarsin:

foydalanuvchi yaratish
foydalanuvchini ko‘rish
foydalanuvchini yangilash
foydalanuvchini o‘chirish
ma’lumotlarni saqlash
API orqali ma’lumot almashish
xatolarni qayd qilish
testlarni ishga tushirish

Shu loyiha davomida ushbu 20 bobda o‘rganilgan Python bilimlarini birlashtiring.

Shu bilan Python kursining asosiy 20 boblik dasturi yakunlanadi.