Asosiy qismga o'tish

Muhit va bog'liqliklar: venv, pip, pyproject.toml

2-bob 15 kod bloki 1384 so'z

Muammo: "menda ishlaydi"

Kodingizni do'stingizga berdingiz, u ishga tushirdi — xato. Sabab deyarli har doim bitta: sizda o'rnatilgan kutubxona unda yo'q, yoki boshqa versiyada.

Python paketlarni global o'rnatadi. Ya'ni ikkita loyiha bitta kompyuterda turli versiyadagi bir kutubxonani talab qilsa, ular to'qnashadi.

python3 qator
import sys, platform
print("Python:", sys.version.split()[0], "|", platform.system())
print("paketlar qayerda:", [p for p in sys.path if "packages" in p][:1])
Chiqish
Python: 3.10.12 | Linux
paketlar qayerda: ['/home/abulqosim/.local/lib/python3.10/site-packages']

venv: har loyihaga o'z muhiti

Virtual muhit — loyiha ichidagi alohida Python. Unga o'rnatilgan paketlar faqat o'sha loyihaga tegishli.

matn3 qator
python3 -m venv .venv
ls .venv
ls .venv/bin | head -8
Chiqish (qaytish kodi 0, 1730 ms)
bin
include
lib
lib64
pyvenv.cfg
Activate.ps1
activate
activate.csh
activate.fish
coverage
coverage-3.10
coverage3
dmypy

.venv/bin/python3 — alohida Python. Uni tekshiramiz:

python2 qator
.venv/bin/python3 -c "import sys; print('venv python:', sys.executable)"
.venv/bin/python3 -m pip list
Chiqish (qaytish kodi 0, 7753 ms)
venv python: /mnt/c/Users/Admin/Desktop/Course Material/Python_Muhandisligi/ish/.venv/bin/python3
Package            Version   Editable project location
------------------ --------- ------------------------------------------------------------------
ast_serialize      0.11.2
certifi            2026.7.22
charset-normalizer 3.5.1
coverage           7.16.2
exceptiongroup     1.3.1
hisobot            0.1.0     /mnt/c/Users/Admin/Desktop/Course Material/Python_Muhandisligi/ish
idna               3.20
iniconfig          2.3.0
librt              0.16.0
mypy               2.3.1
mypy_extensions    1.1.0
packaging          26.3
pathspec           1.1.1
pip                22.0.2
pluggy             1.6.0
Pygments           2.21.0
pytest             9.1.1
pytest-cov         7.1.0
requests           2.32.5
ruff               0.16.9
setuptools         59.6.0
tomli              2.4.1
typing_extensions  4.16.0
urllib3            2.8.0

Yangi muhitda deyarli hech narsa yo'q — pip va standart kutubxona. Bu yaxshi: loyihaga nima kerakligini o'zingiz aniq aytasiz.

:::gotcha activate shart emas Ko'p darsliklarda source .venv/bin/activate yoziladi. U qulay, lekin majburiy emas — .venv/bin/python3 ni to'g'ridan-to'g'ri chaqirsangiz ham o'sha muhit ishlatiladi. Skript va CI da aynan shunday qilish ishonchliroq, chunki activate unutilishi mumkin. :::

Paket o'rnatamiz

python2 qator
.venv/bin/python3 -m pip install --quiet "requests==2.32.5"
.venv/bin/python3 -m pip list
Chiqish (qaytish kodi 0, 15245 ms)
Package            Version   Editable project location
------------------ --------- ------------------------------------------------------------------
ast_serialize      0.11.2
certifi            2026.7.22
charset-normalizer 3.5.1
coverage           7.16.2
exceptiongroup     1.3.1
hisobot            0.1.0     /mnt/c/Users/Admin/Desktop/Course Material/Python_Muhandisligi/ish
idna               3.20
iniconfig          2.3.0
librt              0.16.0
mypy               2.3.1
mypy_extensions    1.1.0
packaging          26.3
pathspec           1.1.1
pip                22.0.2
pluggy             1.6.0
Pygments           2.21.0
pytest             9.1.1
pytest-cov         7.1.0
requests           2.32.5
ruff               0.16.9
setuptools         59.6.0
tomli              2.4.1
typing_extensions  4.16.0
urllib3            2.8.0

Diqqat: requests bitta o'zi kelmadi — u bilan birga to'rtta boshqa paket o'rnatildi (certifi, charset_normalizer, idna, urllib3). Bular — bog'liqliklarning bog'liqliklari.

Shuning uchun pip install dan keyin nima o'rnatilganini bilish kerak:

matn1 qator
.venv/bin/python3 -m pip show requests | grep -E "^(Name|Version|Summary|License|Requires):"
Chiqish (qaytish kodi 0, 5310 ms)
Name: requests
Version: 2.32.5
Summary: Python HTTP for Humans.
License: Apache-2.0
Requires: certifi, charset_normalizer, idna, urllib3

requirements.txt va uning kamchiligi

An'anaviy usul — o'rnatilgan paketlarni faylga yozish:

matn2 qator
.venv/bin/python3 -m pip freeze > requirements.txt
cat requirements.txt
Chiqish (qaytish kodi 0, 6784 ms)
ast_serialize==0.11.2
certifi==2026.7.22
charset-normalizer==3.5.1
coverage==7.16.2
exceptiongroup==1.3.1
# Editable install with no version control (hisobot==0.1.0)
-e /mnt/c/Users/Admin/Desktop/Course Material/Python_Muhandisligi/ish
idna==3.20
iniconfig==2.3.0
librt==0.16.0
mypy==2.3.1
mypy_extensions==1.1.0
packaging==26.3
pathspec==1.1.1
pluggy==1.6.0
Pygments==2.21.0
pytest==9.1.1
pytest-cov==7.1.0
requests==2.32.5
ruff==0.16.9
tomli==2.4.1
typing_extensions==4.16.0
urllib3==2.8.0

Bu fayl bilan boshqa odam aynan o'sha versiyalarni o'rnatadi. Muammo shundaki, u siz nimani so'raganingizni va nima o'z-o'zidan kelganini ajratmaydi. Yuqoridagi faylda beshta paket bor, siz esa faqat bittasini so'ragansiz.

Olti oydan keyin "idna nega kerak edi?" degan savolga javob yo'q.

pyproject.toml: zamonaviy usul

pyproject.toml — loyihaning rasmiy tavsifi. U to'g'ridan-to'g'ri bog'liqliklarni yozadi, qolganini pip o'zi hal qiladi.

shu faylni yaratingpyproject.toml

python19 qator
[project]
name = "hisobot"
version = "0.1.0"
description = "CSV ma'lumotini tekshirib hisobot chiqaradigan asbob"
requires-python = ">=3.10"
dependencies = [
    "requests>=2.32",
]

[project.optional-dependencies]
dev = [
    "pytest>=8",
    "mypy>=1.8",
    "ruff>=0.5",
]

[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"

Uch qism muhim:

Bo'lim Nima uchun
dependencies Dastur ishlashi uchun kerak bo'lganlar
optional-dependencies.dev Faqat ishlab chiqish uchun: test, tur tekshiruvi, linter
requires-python Qaysi Python versiyalarida ishlaydi

Ajratish muhim: serverga pytest va mypy ni o'rnatish shart emas, ular u yerda ishlatilmaydi.

Versiya chegaralarini qanday yozish

python9 qator
qoidalar = [
    ("requests", "yo'q chegara", "har qanday versiya — ertaga buziladi"),
    ("requests==2.32.5", "qat'iy", "takrorlanadi, lekin xavfsizlik yangilanishi kelmaydi"),
    ("requests>=2.32", "minimal", "yangi versiyalar keladi, jumladan buzadiganlari ham"),
    ("requests>=2.32,<3", "oraliq", "katta versiya o'zgarishidan himoya — tavsiya etiladi"),
    ("requests~=2.32.0", "moslik", ">=2.32.0, <2.33.0 bilan bir xil"),
]
import pandas as pd
show(pd.DataFrame(qoidalar, columns=["yozuv", "turi", "ma'nosi"]))
yozuvturima'nosi
requestsyo'q chegarahar qanday versiya — ertaga buziladi
requests==2.32.5qat'iytakrorlanadi, lekin xavfsizlik yangilanishi kelmaydi
requests>=2.32minimalyangi versiyalar keladi, jumladan buzadiganlari ham
requests>=2.32,<3oraliqkatta versiya o'zgarishidan himoya — tavsiya etiladi
requests~=2.32.0moslik>=2.32.0, <2.33.0 bilan bir xil

Amaliy qoida: kutubxona yozayotgan bo'lsangiz keng chegara bering (>=2.32,<3), dastur yozayotgan bo'lsangiz qulflang.

Qulflash: aniq takrorlanadigan o'rnatish

pyproject.toml "2.32 dan yuqori" deydi. Lekin bugun u 2.32.5 ni o'rnatadi, ertaga 2.33.0 ni. Ishlab chiqarishda bu xavfli.

Yechim — lock fayl: aynan qaysi versiya o'rnatilganini yozib qo'yish.

matn3 qator
.venv/bin/python3 -m pip freeze --all > talablar-qulf.txt
wc -l talablar-qulf.txt
head -3 talablar-qulf.txt
Chiqish (qaytish kodi 0, 6180 ms)
25 talablar-qulf.txt
ast_serialize==0.11.2
certifi==2026.7.22
charset-normalizer==3.5.1

Ikki faylning vazifasi boshqa:

Qulf faylida 7 qator bor, requirements.txt da esa 5 ta edi. Farq --all bayrog'idan: u pip va setuptools ni ham yozadi. Bu ataylab — asbobning o'zi ham versiyaga ega va u ham natijaga ta'sir qiladi.

Fayl Kim uchun Nima yozilgan
pyproject.toml Odam uchun "Menga requests kerak, 2.32 dan yangi"
talablar-qulf.txt Mashina uchun Aynan 7 ta paket, aniq versiyalarda

Ikkalasini ham git ga qo'ying.

Loyihani o'rnatamiz

Endi hisobot ni paket sifatida o'rnatish mumkin. Avval minimal tuzilish yasaymiz:

shu faylni yaratingsrc/hisobot/__init__.py

python3 qator
"""CSV ma'lumotini tekshirib hisobot chiqaradigan asbob."""

__version__ = "0.1.0"

shu faylni yaratingsrc/hisobot/hisob.py

python10 qator
"""Statistika: kiritish/chiqarishsiz, faqat hisob."""


def guruh_ortachasi(qatorlar):
    yigindi = {}
    for q in qatorlar:
        g = q["guruh"]
        jami, soni = yigindi.get(g, (0, 0))
        yigindi[g] = (jami + q["baho"], soni + 1)
    return {g: round(jami / soni, 2) for g, (jami, soni) in sorted(yigindi.items())}
python2 qator
.venv/bin/python3 -m pip install --quiet -e .
.venv/bin/python3 -c "import hisobot; print('versiya:', hisobot.__version__); print('joyi:', hisobot.__file__)"
Chiqish (qaytish kodi 0, 23584 ms)
versiya: 0.1.0
joyi: /mnt/c/Users/Admin/Desktop/Course Material/Python_Muhandisligi/ish/src/hisobot/__init__.py

-e — tahrirlanadigan (editable) o'rnatish. Paket nusxalanmaydi; Python sizning src/ papkangizga qaraydi. Faylni o'zgartirsangiz, qayta o'rnatish shart emas.

Buni tekshiramiz — faylni o'zgartiramiz va darhol qayta import qilamiz:

shu faylni yaratingsrc/hisobot/__init__.py

python3 qator
"""CSV ma'lumotini tekshirib hisobot chiqaradigan asbob."""

__version__ = "0.2.0"
python1 qator
.venv/bin/python3 -c "import hisobot; print('versiya endi:', hisobot.__version__)"
Chiqish (qaytish kodi 0, 60 ms)
versiya endi: 0.2.0

Qayta o'rnatmadik, lekin versiya o'zgardi. Ishlab chiqish paytida har doim -e ishlating.

Nega src/ papkasi

src/ ichiga qo'yish ortiqcha ko'rinadi. Sababi aniq: usiz o'rnatilmagan paket ham import qilinadi, chunki joriy papka sys.path da bo'ladi.

bash2 qator
.venv/bin/python3 -c "import sys; print('joriy papka sys.path da:', '' in sys.path or '.' in sys.path)"
cd /tmp && /mnt/c/Users/Admin/Desktop/Course\ Material/Python_Muhandisligi/ish/.venv/bin/python3 -c "import hisobot; print('boshqa papkadan ham ishladi:', hisobot.__version__)"
Chiqish (qaytish kodi 0, 80 ms)
joriy papka sys.path da: True
boshqa papkadan ham ishladi: 0.2.0

Oxirgi buyruq boshqa papkadan ishga tushdi va baribir ishladi — chunki paket haqiqatan o'rnatilgan. Agar src/ bo'lmaganida, testlar loyiha papkasida "ishlagan" bo'lardi, lekin o'rnatishdan keyin foydalanuvchida yiqilardi. src/ bu xatoni erta ochadi.

Xulosa

Tushuncha Asosiy fikr
venv Har loyihaga alohida Python; .venv/bin/python3 ni to'g'ridan-to'g'ri chaqiring
Bog'liqlik zanjiri Bitta paket o'nlab boshqasini tortib keladi
pyproject.toml Siz so'ragan paketlar; odam o'qiydigan ro'yxat
dev guruhi Test va linterlar ishlab chiqarishga kerak emas
Lock fayl Aynan qaysi versiya o'rnatilgani; mashina uchun
pip install -e . Tahrirlanadigan o'rnatish — fayl o'zgarsa darhol amal qiladi
src/ tartibi Tasodifiy import ni oldini oladi; xatoni erta ochadi

Talaba ishi

  1. .venv ni o'chirib, pyproject.toml dan qaytadan tiklang: pip install -e ".[dev]". Nechta paket o'rnatildi?
  2. pyproject.toml ga requests<2 deb yozing va o'rnatib ko'ring. pip qanday xabar beradi?
  3. Ikkita venv yasang va ularga requests ning turli versiyalarini o'rnating. Ikkalasi bir vaqtda yashay oladimi?
  4. pip freeze va pip list --not-required natijalarini solishtiring. Ikkinchisi nima uchun foydaliroq?

Bu bobni bepul o'qidingiz.

Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.

Telegramda yozish Narxlar