3-qism · Professional Python·11-bob
Fayllar, yo'llar va ma'lumot formatlari
pathlib bilan yo'llar, fayllarni ochish rejimlari va kodlash, katta fayllarni oqim bilan o'qish, CSV, JSON va JSONL, pickle xavfi, Parquet va boshqa formatlar, xavfsiz (atomic) yozish.
ML loyihasining katta qismi — fayllar bilan ishlash: datasetlarni o'qish, tozalangan ma'lumotni saqlash, model checkpoint'lari, tajriba natijalari, konfiguratsiyalar, loglar. Bu bobda fayl tizimi bilan xavfsiz va platformadan mustaqil ishlashni hamda AI/ML'da eng ko'p uchraydigan formatlarni o'rganamiz.
pathlib bilan fayl yo'llari: yaratish, qidirish, o'qish va yozish — bobning 1-bo'limidagi zamonaviy usul batafsil.
1. pathlib — yo'llar bilan zamonaviy ishlash#
Eski kodlarda yo'llar satr sifatida va os.path bilan yig'iladi:
import os
path = os.path.join("data", "raw", "reviews.csv") # eski uslubZamonaviy usul — pathlib.Path obyekti:
from pathlib import Path
DATA_DIR = Path("data")
p = DATA_DIR / "raw" / "reviews.csv" # / operatori yo'lni birlashtiradi
p.name # 'reviews.csv'
p.stem # 'reviews'
p.suffix # '.csv'
p.parent # Path('data/raw')
p.with_suffix(".parquet") # Path('data/raw/reviews.parquet')
p.parts # ('data', 'raw', 'reviews.csv')Path Windows'da \, Linux/macOS'da / ishlatadi — kodingiz ikkalasida
ham ishlaydi.
Fayl tizimi amallari#
p.exists() # mavjudmi
p.is_file(), p.is_dir()
p.stat().st_size # hajmi, baytda
p.resolve() # to'liq (absolyut) yo'l
out = Path("outputs") / "run-01"
out.mkdir(parents=True, exist_ok=True) # ichma-ich papkalar; mavjud bo'lsa xato yo'q
p.read_text(encoding="utf-8") # butun faylni satr sifatida
p.write_text("salom", encoding="utf-8") # yozish (eski mazmun o'chadi)
p.read_bytes(), p.write_bytes(b"...")
p.rename(p.with_name("old.csv"))
p.unlink(missing_ok=True) # faylni o'chirishFayllarni qidirish#
data = Path("data")
list(data.glob("*.csv")) # faqat shu papkadagi .csv'lar
list(data.rglob("*.jsonl")) # barcha ichki papkalarda ham
sorted(data.glob("img_*.png")) # tartib kafolatlanmaydi — saralang!
for f in data.iterdir(): # papka ichidagilar
if f.is_file():
print(f.name, f.stat().st_size)Skript joylashuviga nisbatan yo'l#
# src/myproject/config.py
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[2] # config.py → myproject → src → loyiha
DATA_DIR = PROJECT_ROOT / "data"Path("data") — joriy ishchi papkaga nisbatan; skriptni boshqa
papkadan ishga tushirsangiz, boshqa joyni ko'rsatadi. __file__ga nisbatan
yo'l esa har doim bir xil.
2. open() — fayllarni ochish#
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("Birinchi qator\n")
f.write("Ikkinchi qator\n")
with open("notes.txt", encoding="utf-8") as f: # standart rejim — "r"
content = f.read()Rejimlar#
| Rejim | Ma'nosi | Fayl yo'q bo'lsa | Fayl bor bo'lsa |
|---|---|---|---|
"r" | O'qish (standart) | Xato | O'qiydi |
"w" | Yozish | Yaratadi | Mazmunni o'chiradi! |
"a" | Oxiriga qo'shish | Yaratadi | Oxiriga yozadi |
"x" | Faqat yangi fayl yaratish | Yaratadi | Xato (tasodifan ustidan yozishdan himoya) |
"r+" | O'qish va yozish | Xato | — |
+ "b" | Ikkilik (binary): "rb", "wb" | baytlar, encodingsiz |
Kodlash (encoding) — har doim yozing#
3-bobda aytilgandek: matnli faylni ochganda har doim
encoding="utf-8" yozing. Aks holda Python operatsion tizimning standart
kodlashini ishlatadi (Windows'da ko'pincha cp1251 yoki cp1252) va
o'zbekcha/ruscha matn buziladi.
Kodlashi noma'lum fayl uchun:
with open(path, encoding="utf-8", errors="replace") as f: # buzilgan baytlar → �
text = f.read()Excel'dan saqlangan CSV ko'pincha utf-8-sig (boshida BOM belgisi bilan)
bo'ladi — birinchi ustun nomi "name" bo'lib qolsa, sabab shu:
encoding="utf-8-sig" ishlating.
O'qish usullari#
with open(path, encoding="utf-8") as f:
text = f.read() # butun fayl — bitta satr (kichik fayllar uchun)
with open(path, encoding="utf-8") as f:
lines = f.readlines() # qatorlar ro'yxati (\n bilan) — butun fayl xotirada
with open(path, encoding="utf-8") as f:
for line in f: # ✅ qatorma-qator — xotira tejamkor (7-bob!)
process(line.rstrip("\n"))Fayl obyekti — iterator (7-bob): for line in f bir vaqtda faqat
bitta qatorni xotirada ushlaydi. 50 GB log faylni ham shunday o'qish
mumkin.
Ikkilik fayllar va bo'laklab o'qish#
import hashlib
def sha256(path: Path, chunk_size: int = 1 << 20) -> str:
"""Katta faylning hash'ini 1 MB bo'laklab hisoblaydi."""
h = hashlib.sha256()
with open(path, "rb") as f:
while chunk := f.read(chunk_size):
h.update(chunk)
return h.hexdigest()Model fayllari yoki datasetlar yuklab olinganda ularning butunligini shu usulda tekshirishadi.
3. CSV#
CSV — eng sodda jadval formati, lekin tuzoqlari ko'p: matn ichidagi
vergullar, qo'shtirnoqlar, yangi qatorlar. Hech qachon line.split(",")
bilan o'qimang:
"Vali, kichik",92 # split(",") → ['"Vali', ' kichik"', '92'] ❌Standart csv moduli bularni to'g'ri qayta ishlaydi:
import csv
with open("talabalar.csv", encoding="utf-8", newline="") as f:
for row in csv.DictReader(f): # har qator — lug'at
print(row["ism"], int(row["ball"])) # qiymatlar har doim SATR — o'zingiz aylantiring
rows = [{"ism": "Ali", "ball": 85}, {"ism": "Vali, kichik", "ball": 92}]
with open("natija.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["ism", "ball"])
writer.writeheader()
writer.writerows(rows)newline="" — csv moduli qator oxirlarini o'zi boshqarishi uchun
(aks holda Windows'da bo'sh qatorlar paydo bo'ladi).
Amalda katta CSV'lar bilan Pandas ishlatiladi (pd.read_csv, 20-bob)
— lekin kichik skriptlar va qo'shimcha bog'liqliksiz vazifalar uchun csv
moduli ideal.
4. JSON#
JSON — API'lar, konfiguratsiyalar va LLM javoblarining tili.
import json
data = {"ism": "Aziz", "yosh": 25, "faol": True, "telefon": None, "baholar": [5, 4]}
s = json.dumps(data, ensure_ascii=False, indent=2) # obyekt → satr
obj = json.loads(s) # satr → obyekt
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2) # faylga
with open("data.json", encoding="utf-8") as f:
obj = json.load(f) # fayldandumps/loads — satr bilan (s — string), dump/load — fayl bilan.
Python ↔ JSON tiplari#
| Python | JSON | Izoh |
|---|---|---|
dict | object | Kalitlar faqat satr bo'ladi ({1: "a"} → {"1": "a"}) |
list, tuple | array | Tuple qaytishda list bo'lib qoladi |
str | string | |
int, float | number | NaN, inf — standart JSON emas! |
True/False | true/false | |
None | null | |
set, datetime, Decimal, Path, NumPy tiplari | — | TypeError: Object of type ... is not JSON serializable |
ensure_ascii=False — o'zbek/rus harflari "а" ko'rinishida emas,
o'zicha yoziladi.
Seriyalab bo'lmaydigan tiplar uchun default:
from datetime import datetime
json.dumps({"vaqt": datetime(2026, 10, 1)}, default=str)
# '{"vaqt": "2026-10-01 00:00:00"}'LLM javobidan JSON ajratib olish#
Model ba'zan JSON'ni qo'shimcha matn yoki ```json bloki ichida
qaytaradi. Mustahkam ajratish:
import json
import re
def extract_json(text: str) -> dict:
"""Model javobidan birinchi JSON obyektini ajratib oladi."""
fenced = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", text, re.DOTALL)
candidate = fenced.group(1) if fenced else text[text.find("{"): text.rfind("}") + 1]
try:
return json.loads(candidate)
except json.JSONDecodeError as e:
raise ValueError(f"Javobda yaroqli JSON topilmadi: {text[:200]!r}") from eBu "favqulodda" usul. Yaxshiroq yo'l — API'ning structured outputs imkoniyati va Pydantic bilan validatsiya (15 va 23-boblar): model sxemaga mos JSON qaytarishga kafolat beradi.
5. JSONL — AI datasetlarining formati#
JSON Lines — har qatorda bitta JSON obyekt:
{"prompt": "Poytaxt qaysi?", "completion": "Toshkent"}
{"prompt": "2+2?", "completion": "4"}
{"prompt": "Eng uzun daryo?", "completion": "Amudaryo"}Nega oddiy JSON massiv emas?
- Oqim bilan o'qish: qatorma-qator — butun faylni yuklash shart emas;
- Oxiriga qo'shish oson:
"a"rejimida bitta qator yozish kifoya; - Buzilishga chidamli: bitta buzilgan qator butun faylni yaroqsiz qilmaydi;
- Parallel qayta ishlash: faylni qatorlar bo'yicha bo'lish oson.
Fine-tuning datasetlari, Batch API so'rovlari, evaluation natijalari,
loglar — hammasi JSONL. 7-bobdagi read_jsonl generatorini eslang. Yozish:
def append_jsonl(path: Path, record: dict) -> None:
with open(path, "a", encoding="utf-8") as f:
f.write(json.dumps(record, ensure_ascii=False) + "\n")6. Pickle — qulay, lekin xavfli#
pickle deyarli har qanday Python obyektini baytlarga aylantiradi:
import pickle
with open("model.pkl", "wb") as f:
pickle.dump(model, f)
with open("model.pkl", "rb") as f:
model = pickle.load(f)Boshqa cheklovlar: pickle Python versiyasi va kutubxona versiyasiga bog'liq (eski pickle yangi kod bilan ochilmasligi mumkin), boshqa tillar o'qiy olmaydi. Qoida: o'zingizning vaqtinchalik keshingiz uchun — mayli; uzoq saqlash va almashish uchun — JSON, Parquet, safetensors.
7. Boshqa formatlar — qisqa xarita#
| Format | Nima uchun | Python'da |
|---|---|---|
| CSV | Oddiy jadvallar, Excel bilan almashish | csv, pandas.read_csv |
| JSON | Konfiguratsiya, API | json |
| JSONL | Datasetlar, loglar, batch so'rovlar | json + qatorlar |
| Parquet | Katta jadvallar: ustunli, siqilgan, tiplari saqlanadi | pandas.read_parquet (pyarrow) |
| YAML | Inson yozadigan konfiguratsiya (izohlar bilan) | pyyaml — yaml.safe_load! |
| TOML | Konfiguratsiya (pyproject.toml) | tomllib (standart, faqat o'qish) |
| safetensors | Model og'irliklari (xavfsiz) | safetensors |
| NPY/NPZ | NumPy massivlari | np.save, np.load |
| SQLite | Kichik ma'lumotlar bazasi bitta faylda | sqlite3 (standart) |
Parquet haqida alohida: 1 GB CSV ko'pincha 100–200 MB Parquet'ga aylanadi, 5–20 baravar tez o'qiladi va ustun tiplarini (sana, butun son, kategoriya) saqlaydi. Katta datasetlar uchun standart.
import tomllib
with open("pyproject.toml", "rb") as f: # tomllib binary rejim talab qiladi
cfg = tomllib.load(f)
print(cfg["project"]["name"])8. Xavfsiz yozish: atomic write#
Tasavvur qiling: 3 soatlik hisob-kitob natijasini results.jsonga
yozyapsiz va yozish o'rtasida dastur yiqildi (xotira tugadi, Ctrl+C,
server o'chdi). Natija: yarim yozilgan, buzilgan fayl — va eski
natija ham yo'q.
Yechim — avval vaqtinchalik faylga yozib, keyin bir amalda almashtirish:
import json
import os
import tempfile
from pathlib import Path
def atomic_write_json(path: Path, data) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
fd, tmp = tempfile.mkstemp(dir=path.parent, prefix=f".{path.name}.", suffix=".tmp")
try:
with os.fdopen(fd, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
f.flush()
os.fsync(f.fileno()) # diskka haqiqatan yozilganiga ishonch
os.replace(tmp, path) # atomik: yo eski fayl, yo yangi — oraliq holat yo'q
except BaseException:
Path(tmp).unlink(missing_ok=True)
raiseos.replace bitta fayl tizimi ichida atomik — o'quvchi hech qachon yarim
fayl ko'rmaydi. Checkpoint'lar, kesh fayllari va natijalar uchun shu
naqshdan foydalaning.
9. shutil, tempfile va boshqa yordamchilar#
import shutil
import tempfile
shutil.copy2("a.csv", "backup/a.csv") # nusxa (metama'lumot bilan)
shutil.copytree("data", "data_backup") # butun papka
shutil.rmtree("tmp_outputs") # papkani butunlay o'chirish — EHTIYOT!
shutil.move("a.csv", "archive/")
shutil.make_archive("results", "zip", "outputs") # outputs/ → results.zip
shutil.disk_usage("/").free # bo'sh joy
with tempfile.TemporaryDirectory() as tmp: # blokdan chiqqanda o'chiriladi
work = Path(tmp) / "work.txt"
work.write_text("vaqtinchalik", encoding="utf-8")TemporaryDirectory testlarda juda foydali (16-bobda pytest'ning
tmp_path fixture'i bilan buni yanada osonroq qilamiz).
10. Amaliyot: dataset tayyorlash skripti#
CSV'dan sharhlarni o'qib, tozalab, train/val'ga bo'lib, JSONL sifatida saqlaydigan to'liq skript:
"""reviews.csv → train.jsonl + val.jsonl"""
import csv
import json
import logging
import random
from pathlib import Path
log = logging.getLogger(__name__)
ROOT = Path(__file__).resolve().parent
RAW = ROOT / "data" / "raw" / "reviews.csv"
OUT = ROOT / "data" / "processed"
VALID_LABELS = {"positive", "negative", "neutral"}
def read_reviews(path: Path):
with open(path, encoding="utf-8-sig", newline="") as f:
for n, row in enumerate(csv.DictReader(f), start=2): # 1-qator — sarlavha
text = (row.get("text") or "").strip()
label = (row.get("label") or "").strip().lower()
if not text or label not in VALID_LABELS:
log.warning("%s:%d o'tkazib yuborildi (text=%r, label=%r)", path.name, n, text[:30], label)
continue
yield {"text": " ".join(text.split()), "label": label}
def write_jsonl(path: Path, records: list[dict]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
for r in records:
f.write(json.dumps(r, ensure_ascii=False) + "\n")
def main(val_ratio: float = 0.1, seed: int = 42) -> None:
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s")
records = list(read_reviews(RAW))
unique = list({r["text"]: r for r in records}.values()) # dublikat matnlarni olib tashlash
log.info("%d ta yozuv, %d ta dublikat olib tashlandi", len(unique), len(records) - len(unique))
random.Random(seed).shuffle(unique)
n_val = max(1, int(len(unique) * val_ratio))
write_jsonl(OUT / "val.jsonl", unique[:n_val])
write_jsonl(OUT / "train.jsonl", unique[n_val:])
log.info("train=%d, val=%d → %s", len(unique) - n_val, n_val, OUT)
if __name__ == "__main__":
main()Bu skriptda bobning deyarli hamma g'oyasi bor: __file__ga nisbatan
yo'llar, utf-8-sig (Excel CSV), csv.DictReader, generator bilan o'qish,
buzilgan qatorlarni logga yozish, dublikatlarni lug'at orqali olib tashlash,
seed bilan takrorlanuvchan aralashtirish, JSONL yozish.
Nima noto'g'ri ketishi mumkin#
| Belgi | Sabab | Yechim |
|---|---|---|
Buzilgan o'zbek/rus harflari, UnicodeDecodeError | encoding ko'rsatilmagan | encoding="utf-8" (Excel CSV: utf-8-sig) |
Birinchi ustun nomi name | BOM | encoding="utf-8-sig" |
FileNotFoundError, garchi fayl bor bo'lsa ham | Joriy papka boshqa | Path(__file__).parent ga nisbatan yo'l |
| Fayl bo'shab qoldi | "w" rejimida ochildi | "a" yoki "x"; atomik yozish |
MemoryError katta faylda | read() / readlines() | for line in f |
| CSV'da ustunlar siljigan | split(",") | csv moduli yoki Pandas |
| Windows'da CSV'da bo'sh qatorlar | newline="" yo'q | open(..., newline="") |
Object of type float32 is not JSON serializable | NumPy tipi | float(x) yoki x.item() |
| Har ishga tushirishda boshqa natija | glob tartibi | sorted(glob(...)) |
Yuklangan .pkl ochildi va... | pickle kod bajaradi | Ishonchsiz pickle'ni ochmang; safetensors/JSON |
1. Papka statistikasi
folder_report(root) funksiyasini yozing: papkadagi barcha fayllarni
(ichki papkalar bilan) ko'rib, kengaytmalar bo'yicha soni va umumiy hajmini
(MB'da, 2 xona kasr bilan) jadval qilib chiqarsin, eng katta 5 faylni
ko'rsatsin.
Maslahatni ko'rsatish
Counter(p.suffix.lower() for p in root.rglob('*') if p.is_file()); hajm uchun sum(p.stat().st_size ...).
2. CSV → JSONL konvertor
CSV faylni JSONL'ga aylantiruvchi CLI skript yozing (python convert.py input.csv output.jsonl):
sonli ko'rinadigan qiymatlarni int/floatga aylantirsin, bo'sh qiymatlarni
null qilsin, yozilgan qatorlar sonini chiqarsin. sys.argv ishlating
(18-bobda argparseni ko'ramiz).
Maslahatni ko'rsatish
csv.DictReader + json.dumps(row, ensure_ascii=False); sonli ustunlar uchun 10-bobdagi safe_float.
3. Natijalar jurnali
ML tajribalari jurnalini yozing: log_run(params: dict, metrics: dict)
runs.jsonlga vaqt belgisi bilan qator qo'shsin (NumPy sonlari ham to'g'ri
yozilsin), best_run(metric) esa eng yaxshi tajribani qaytarsin.
Maslahatni ko'rsatish
Har bir tajriba — bitta JSONL qator (append). O'qishda max(records, key=lambda r: r['metrics']['acc']).
4. Atomik yozishni sinash
atomic_write_json va oddiy json.dumpni solishtiring: yozish o'rtasida
xato ko'taradigan "yomon" obyekt yarating (masalan, default funksiyasi
uchinchi chaqiruvda RuntimeError ko'tarsin). Har ikki holatda ham avvalgi
fayl mazmuniga nima bo'lishini tekshiring.
- 01pathlib.Path: / bilan birlashtirish, name/stem/suffix/parent, mkdir(parents=True, exist_ok=True), glob/rglob (saralang!).
- 02Yo'llarni Path(__file__) ga nisbatan quring — joriy papkaga bog'liq bo'lmasin.
- 03open: har doim with va encoding='utf-8'; 'w' faylni darhol bo'shatadi; katta fayllarni qatorma-qator o'qing.
- 04CSV — csv moduli (split emas), newline=''; JSON — dump/load, ensure_ascii=False, NumPy tiplarini aylantiring.
- 05JSONL — AI datasetlari va loglar uchun standart: oqim, qo'shish, buzilishga chidamlilik.
- 06pickle va yaml.load ishonchsiz manbadan — kod bajarilishi xavfi.
- 07Muhim fayllarni atomik yozing: vaqtinchalik fayl + os.replace.
Mustahkamlash
Test va amaliy masalalar
Avval testni ishlang — har javobdan keyin izoh chiqadi. Keyin masalalarni shu yerning o'zida yechib, brauzerdagi haqiqiy Python bilan avtomatik tekshiring. Natijalaringiz kurs progressi sahifasida jamlanadi.
Bilimni tekshirish
Bob bo'yicha test
12 ta savol · har javobdan keyin to'g'ri yoki xatoligi va izoh ko'rsatiladi · oxirida natija foizda.
Amaliy masalalar
Kodni yozing va «Tekshirish»ni bosing (yoki Ctrl/⌘ + Enter). Kodingiz shu brauzerda saqlanib turadi.
01JSONL yozish va o'qish
write_jsonl(path, records) — har yozuvni bitta qatorga (ensure_ascii=False) yozib, yozilganlar sonini qaytarsin. read_jsonl(path) — generator: bo'sh qatorlarni o'tkazib, buzilgan qatorlarni (JSON emas) ham o'tkazib, lug'atlarni chiqarsin.
02CSV'dan statistika
price_stats(csv_text) — name,city,price ustunli CSV matnidan (io.StringIO + csv.DictReader) har shahar uchun o'rtacha narxni lug'at qilib qaytarsin (2 xona yaxlitlab). Narxi bo'sh yoki son bo'lmagan qatorlar e'tiborsiz.
03Atomik yozish
atomic_write_text(path, text) — matnni avval shu papkadagi vaqtinchalik faylga yozib, keyin os.replace bilan almashtirsin. Xato bo'lsa vaqtinchalik fayl o'chirilsin. Funksiya pathlib.Path qabul qiladi.