OzbekPython / Bob 15

Fayllar bilan işlaş

Fayllarni oçiş rejimlari, with bloki, öqiş va yoziş, pathlib, şuningdek csv va json formatlari bilan işlaş.

Örta daraja18 daqiqa15 kod misoli15 / 24

Nega fayllar kerak?

Hozirgaça yozgan dasturlarimiz bitta kamçilikka ega edi: dastur tugaşi bilan barça maʼlumotlar yöqolardi. Özgaruvçilar operativ xotirada (RAM) yaşaydi va kompyuter öçsa yoki dastur yopilsa, ular ham öçadi.

Maʼlumotni uzoq saqlaş uçun uni faylga yozamiz. Fayllar diskda saqlanadi va ertaga ham, bir yildan keyin ham öqilişi mumkin. Talabalar baholari, dökon hisobi, sozlamalar, kundalik yozuvlar — hammasi fayllarda yaşaydi.

open() funksiyasi va rejimlar

Fayl bilan işlaş uçun avval uni open() funksiyasi bilan oçamiz. U ikkita asosiy parametr oladi: fayl nomi va rejim (mode) — faylni nima maqsadda oçayotganimiz.

RejimMaʼnosiFayl yöq bölsaFayl bor bölsa
"r"Öqiş (standart rejim)FileNotFoundErrorBoşidan öqiydi
"w"YozişYaratadiIçini butunlay öçiradi
"a"Oxiriga qöşişYaratadiOxiriga yozadi
"x"Faqat yangi fayl yaratişYaratadiFileExistsError
"r+"Ham öqiş, ham yozişFileNotFoundErrorBoşidan boşlaydi
"b"Ikkilik rejim (boşqalarga qöşiladi)—"rb", "wb" kabi

"b" rejimi rasmlar, audio, PDF kabi matn bölmagan fayllar uçun işlatiladi. Bunday fayllardan matn emas, bytes öqiladi.

encoding="utf-8" nega muhim?

Kompyuter matnni raqamlar körinişida saqlaydi. Qaysi harf qaysi raqamga mos kelişini kodlaş (encoding) belgilaydi. Agar uni körsatmasangiz, Python operatsion tizimning standart kodlaşini oladi — Windows da bu köpinça UTF-8 emas. Natijada "ö", "ğ" kabi harflar va ʼ belgisi buzilib çiqadi.

Şuning uçun matnli fayllar bilan işlaganda har doim encoding="utf-8" deb yozing.

with bloki — faylni xavfsiz oçiş

Oçilgan faylni iş tugagaç yopiş kerak (close()). Yopilmagan fayl xotirani band qiladi, yozilgan maʼlumot esa diskka töliq tuşmay qolişi mumkin. Agar örtada xato yuz bersa, close() umuman çaqirilmay qoladi.

with bloki bu muammoni hal qiladi: blokdan çiqqanda — xato bölsa ham — fayl avtomatik yopiladi.

Python
with open("salom.txt", "w", encoding="utf-8") as f:
    f.write("Assalomu alaykum!\n")
    f.write("Bugun havo oçiq, +24°C.\n")

with open("salom.txt", encoding="utf-8") as f:
    print(f.read())

print("Fayl yopildimi?", f.closed)

Natija:

Natija
Assalomu alaykum!
Bugun havo oçiq, +24°C.

Fayl yopildimi? True

f.write() qator oxiriga \n qöşmaydi — uni özingiz yozişingiz kerak. print() dan farqi şunda.

Faylga yoziş: write va writelines

write() bitta satr yozadi, writelines() esa satrlar röyxatini birdaniga yozadi (u ham \n qöşmaydi). "a" rejimida esa yangi maʼlumot fayl oxiriga qöşiladi.

Python
mahsulotlar = ["non\n", "sut\n", "tuxum\n"]

with open("xarid.txt", "w", encoding="utf-8") as f:
    f.write("Xarid röyxati:\n")
    f.writelines(mahsulotlar)

# Keyinroq yana ikki mahsulot qöşamiz
with open("xarid.txt", "a", encoding="utf-8") as f:
    f.write("pomidor\n")
    print("guruç", file=f)   # print() ham faylga yoza oladi

with open("xarid.txt", encoding="utf-8") as f:
    print(f.read())

Natija:

Natija
Xarid röyxati:
non
sut
tuxum
pomidor
guruç

print(..., file=f) usuli qulay: u qator oxiriga \n ni özi qöşadi va bir neçta qiymatni probel bilan ajratib yozadi.

"x" rejimi — tasodifan ustidan yozib yubormaslik

Python
from pathlib import Path
Path("muhim.txt").unlink(missing_ok=True)  # misolni qayta işga tuşiriş uçun eski faylni öçiramiz

with open("muhim.txt", "x", encoding="utf-8") as f:
    f.write("Birinçi nusxa")

try:
    with open("muhim.txt", "x", encoding="utf-8") as f:
        f.write("Ikkinçi nusxa")
except FileExistsError:
    print("Fayl allaqaçon mavjud — ustidan yozilmadi.")

Natija:

Natija
Fayl allaqaçon mavjud — ustidan yozilmadi.

Fayldan öqiş

Öqişning bir neça usuli bor:

  • f.read() — butun faylni bitta satr sifatida öqiydi.
  • f.readline() — faqat bitta qatorni öqiydi (keyingi çaqiruv keyingi qatorni beradi).
  • f.readlines() — barça qatorlarni röyxat qilib qaytaradi.
  • for qator in f: — qatorlarni birma-bir aylanib çiqadi. Eng tavsiya etiladigan usul, çunki butun faylni xotiraga yuklamaydi.
Python
with open("şaharlar.txt", "w", encoding="utf-8") as f:
    f.write("Toşkent\nSamarqand\nBuxoro\nXiva\n")

with open("şaharlar.txt", encoding="utf-8") as f:
    birinchi = f.readline()
    ikkinchi = f.readline()
    print("readline:", repr(birinchi), repr(ikkinchi))

with open("şaharlar.txt", encoding="utf-8") as f:
    print("readlines:", f.readlines())

with open("şaharlar.txt", encoding="utf-8") as f:
    for raqam, qator in enumerate(f, start=1):
        print(raqam, qator.strip())

Natija:

Natija
readline: 'Toşkent\n' 'Samarqand\n'
readlines: ['Toşkent\n', 'Samarqand\n', 'Buxoro\n', 'Xiva\n']
1 Toşkent
2 Samarqand
3 Buxoro
4 Xiva

Eʼtibor bering: har bir qator oxirida \n belgisi qoladi. Uni olib taşlaş uçun strip() (yoki faqat öng tomondan — rstrip("\n")) işlatiladi.

seek va tell — fayl içidagi "kursor"

Oçilgan faylda xuddi matn muharriridagi kabi körinmas kursor bor. Har bir öqiş yoki yoziş uni oldinga suradi. tell() kursor joyini (baytlarda) aytadi, seek(n) esa uni n-baytga köçiradi.

Python
with open("alifbo.txt", "w", encoding="utf-8") as f:
    f.write("ABCDEFGHIJ")

with open("alifbo.txt", encoding="utf-8") as f:
    print(f.read(3), "| kursor:", f.tell())
    print(f.read(3), "| kursor:", f.tell())
    f.seek(0)  # boşiga qaytamiz
    print(f.read(), "| kursor:", f.tell())

Natija:

Natija
ABC | kursor: 3
DEF | kursor: 6
ABCDEFGHIJ | kursor: 10

seek(0) faylni qayta oçmasdan boşidan öqiş uçun foydali. "r+" rejimida esa seek() yordamida faylning kerakli joyiga yoziş ham mumkin.

Faylni özgartiriş: öqi → özgartir → yoz

Faylning örtasidagi bitta sözni "joyida" almaştiriş qiyin. Odatiy va işonçli usul — uç qadam:

  1. Faylni töliq öqib oliş.
  2. Matnni xotirada özgartiriş.
  3. Natijani "w" rejimida qayta yoziş.
Python
with open("narxlar.txt", "w", encoding="utf-8") as f:
    f.write("non: 4000\nsut: 12000\nşakar: 15000\n")

# 1. Öqiymiz
with open("narxlar.txt", encoding="utf-8") as f:
    qatorlar = f.readlines()

# 2. Özgartiramiz: hamma narxni 10% oşiramiz
yangi = []
for qator in qatorlar:
    nomi, narx = qator.strip().split(": ")
    yangi.append(f"{nomi}: {round(int(narx) * 1.1)}\n")

# 3. Qayta yozamiz
with open("narxlar.txt", "w", encoding="utf-8") as f:
    f.writelines(yangi)

with open("narxlar.txt", encoding="utf-8") as f:
    print(f.read())

Natija:

Natija
non: 4400
sut: 13200
şakar: 16500

pathlib — fayl yöllari bilan zamonaviy işlaş

pathlib moduli fayl va papkalarni obyekt sifatida ifodalaydi. U Windows (\) va macOS/Linux (/) yöllari orasidagi farqni özi hal qiladi va köp işni bitta qatorda bajaradi.

Python
from pathlib import Path

papka = Path("kundalik")
papka.mkdir(exist_ok=True)          # papka yaratiş (bor bölsa xato bermaydi)

fayl = papka / "duşanba.txt"       # / belgisi yöllarni birlaştiradi
fayl.write_text("Python darsini takrorladim.\n", encoding="utf-8")
(papka / "seşanba.txt").write_text("Fayllar bobini öqidim.\n", encoding="utf-8")
(papka / "rejalar.md").write_text("- Maşqlarni bajariş\n", encoding="utf-8")

print("Mavjudmi?", fayl.exists())
print("Nomi:", fayl.name, "| kengaytmasi:", fayl.suffix, "| asosiy nomi:", fayl.stem)
print("Mazmuni:", fayl.read_text(encoding="utf-8").strip())

print("Barça .txt fayllar:")
for f in sorted(papka.glob("*.txt")):
    print(" -", f.name)

Natija:

Natija
Mavjudmi? True
Nomi: duşanba.txt | kengaytmasi: .txt | asosiy nomi: duşanba
Mazmuni: Python darsini takrorladim.
Barça .txt fayllar:
 - duşanba.txt
 - seşanba.txt

Path ning foydali imkoniyatlari:

  • exists(), is_file(), is_dir() — mavjudlik va turini tekşiriş.
  • read_text() / write_text() — butun faylni bitta qatorda öqiş/yoziş (içida with işlatiladi).
  • glob("*.txt") — andozaga mos fayllarni topiş; rglob() esa içki papkalarni ham qidiradi.
  • unlink() — faylni öçiriş, rename() — nomini özgartiriş.

csv moduli — jadval körinişidagi maʼlumotlar

CSV (vergul bilan ajratilgan qiymatlar) — jadvallarni saqlaşning eng oddiy formati. Excel va Google Sheets uni bemalol oçadi. Uni split(",") bilan qölda ajratiş mumkin, lekin qiymat içida vergul yoki qöştirnoq bölsa, xato çiqadi. csv moduli bunday holatlarni töğri hal qiladi.

Python
import csv

kitoblar = [
    {"nomi": "Ötkan kunlar", "muallif": "Abdulla Qodiriy", "narx": 85000},
    {"nomi": "Mehrobdan çayon", "muallif": "Abdulla Qodiriy", "narx": 78000},
    {"nomi": "Ufq", "muallif": "Said Ahmad", "narx": 92000},
]

with open("kitoblar.csv", "w", encoding="utf-8", newline="") as f:
    yozuvchi = csv.DictWriter(f, fieldnames=["nomi", "muallif", "narx"])
    yozuvchi.writeheader()
    yozuvchi.writerows(kitoblar)

with open("kitoblar.csv", encoding="utf-8", newline="") as f:
    for qator in csv.DictReader(f):
        print(f"{qator['nomi']:<18} {int(qator['narx']):>7} söm")

Natija:

Natija
Ötkan kunlar         85000 söm
Mehrobdan çayon      78000 söm
Ufq                  92000 söm

DictReader har bir qatorni luğat qilib beradi, kalitlar esa sarlavha qatoridan olinadi. Eʼtibor bering: CSV dan öqilgan barça qiymatlar matn, şuning uçun narxni int() ga aylantirdik. newline="" parametri esa Windows da ortiqça böş qatorlar paydo bölişining oldini oladi.

json moduli — tuzilmali maʼlumotlar

JSON — luğat va röyxatlarni matn körinişida saqlaş formati. Veb-saytlar, API lar va sozlama fayllari asosan şu formatda işlaydi. Python luğati va JSON bir-biriga juda öxşaydi.

  • json.dump(obyekt, fayl) — faylga yozadi, json.load(fayl) — fayldan öqiydi.
  • json.dumps(obyekt) — satrga aylantiradi, json.loads(satr) — satrdan öqiydi.
Python
import json
from pathlib import Path

sozlamalar = {
    "til": "uz",
    "mavzu": "qoronği",
    "şrift_olçami": 14,
    "sevimli_şaharlar": ["Toşkent", "Istanbul"],
    "bildirişnoma": True,
}

fayl = Path("sozlamalar.json")
with fayl.open("w", encoding="utf-8") as f:
    json.dump(sozlamalar, f, ensure_ascii=False, indent=2)

print(fayl.read_text(encoding="utf-8"))

with fayl.open(encoding="utf-8") as f:
    yuklangan = json.load(f)
print(type(yuklangan), yuklangan["sevimli_şaharlar"][1])

Natija:

Natija
{
  "til": "uz",
  "mavzu": "qoronği",
  "şrift_olçami": 14,
  "sevimli_şaharlar": [
    "Toşkent",
    "Istanbul"
  ],
  "bildirişnoma": true
}
<class 'dict'> Istanbul

ensure_ascii=False harflarni ʻ kabi kodlarga aylantirmasdan, öz holiça yozadi; indent=2 esa faylni çiroyli va öqişli qiladi. Python True qiymati JSON da true bölib yozilganiga eʼtibor bering.

Amaliy loyiha: baholar fayli → örtaça hisobot

Vazifa: öqituvçi talabalar baholarini CSV faylida saqlaydi. Dastur şu faylni öqib, har bir talabaning örtaça bahosini hisoblaşi, natijani çiroyli hisobot fayliga yozişi va JSON körinişida ham saqlaşi kerak. Fayldagi buzilgan qatorlar dasturni töxtatmasligi lozim.

Python
import csv
import json
from pathlib import Path

# 0. Sinov uçun baholar faylini yaratamiz
Path("baholar.csv").write_text(
    "ism,matematika,fizika,ingliz_tili\n"
    "Aziza,92,88,95\n"
    "Bobur,75,81,68\n"
    "Çaros,88,94,90\n"
    "Davron,60,abc,72\n"
    "Elnora,99,97,100\n",
    encoding="utf-8",
)


def baho_harfi(ortacha: float) -> str:
    if ortacha >= 90:
        return "A"
    if ortacha >= 80:
        return "B"
    if ortacha >= 70:
        return "C"
    return "D"


# 1. Öqiymiz va hisoblaymiz
natijalar = []
with open("baholar.csv", encoding="utf-8", newline="") as f:
    for qator in csv.DictReader(f):
        ism = qator.pop("ism")
        try:
            sonlar = [int(v) for v in qator.values()]
        except ValueError:
            print(f"Ogohlantiriş: {ism} qatorida yaroqsiz baho bor, ötkazib yuborildi.")
            continue
        ortacha = sum(sonlar) / len(sonlar)
        natijalar.append({"ism": ism, "ortaça": round(ortacha, 1), "baho": baho_harfi(ortacha)})

natijalar.sort(key=lambda n: n["ortaça"], reverse=True)

# 2. Matnli hisobot yozamiz
with open("hisobot.txt", "w", encoding="utf-8") as f:
    print("ÖRTAÇA BAHOLAR HISOBOTI", file=f)
    print("-" * 28, file=f)
    for o, n in enumerate(natijalar, start=1):
        print(f"{o}. {n['ism']:<8} {n['ortaça']:>5}  ({n['baho']})", file=f)
    sinf = sum(n["ortaça"] for n in natijalar) / len(natijalar)
    print("-" * 28, file=f)
    print(f"Sinf örtaçasi: {sinf:.1f}", file=f)

# 3. JSON ga ham saqlaymiz
Path("hisobot.json").write_text(json.dumps(natijalar, ensure_ascii=False, indent=2), encoding="utf-8")

print(Path("hisobot.txt").read_text(encoding="utf-8"))
print("JSON yozuvlar soni:", len(json.loads(Path("hisobot.json").read_text(encoding="utf-8"))))

Natija:

Natija
Ogohlantiriş: Davron qatorida yaroqsiz baho bor, ötkazib yuborildi.
ÖRTAÇA BAHOLAR HISOBOTI
----------------------------
1. Elnora    98.7  (A)
2. Aziza     91.7  (A)
3. Çaros     90.7  (A)
4. Bobur     74.7  (C)
----------------------------
Sinf örtaçasi: 89.0

JSON yozuvlar soni: 4

Bu kiçik dasturda bobning deyarli hammasi işlatildi: pathlib bilan yoziş, csv.DictReader bilan öqiş, try/except bilan buzilgan maʼlumotni çetlab ötiş, print(file=f) bilan hisobot yoziş va json bilan saqlaş.

Xulosa

  • Faylni open(nom, rejim, encoding="utf-8") bilan oçing va har doim with blokidan foydalaning.
  • "r" — öqiş, "w" — ustidan yoziş, "a" — qöşiş, "x" — faqat yangi fayl, "b" — ikkilik rejim.
  • Katta fayllarni for qator in f: bilan qatorma-qator öqing; strip() bilan \n ni olib taşlang.
  • seek() va tell() fayl içidagi kursorni boşqaradi.
  • Faylni özgartiriş: öqi → xotirada özgartir → qayta yoz.
  • pathlib.Path yöllar bilan zamonaviy işlaş usuli; csv jadvallar, json esa tuzilmali maʼlumotlar uçun.

Maşqlar

  1. kundalik.txt fayliga uçta yozuvni "a" rejimida (har birini alohida with bilan) qöşing, söng faylni öqib, neçta qator borligini çiqaring.
Yeçim
Python
from pathlib import Path

Path("kundalik.txt").unlink(missing_ok=True)  # toza boşlaş uçun

for yozuv in ["Ertalab yugurdim", "Kitob öqidim", "Python maşq qildim"]:
    with open("kundalik.txt", "a", encoding="utf-8") as f:
        f.write(yozuv + "\n")

with open("kundalik.txt", encoding="utf-8") as f:
    qatorlar = f.readlines()
print("Qatorlar soni:", len(qatorlar))
  1. Matnli fayl yarating va undagi sözlar sonini, eng uzun sözni hamda "python" sözi neça marta uçraganini (katta-kiçik harfga qaramasdan) hisoblang.
Yeçim
Python
from pathlib import Path

fayl = Path("matn.txt")
fayl.write_text("Python oddiy til. Men python bilan dasturlaşni örganyapman. PYTHON zör!", encoding="utf-8")

sozlar = [s.strip(".,!?").lower() for s in fayl.read_text(encoding="utf-8").split()]
print("Sözlar soni:", len(sozlar))
print("Eng uzun söz:", max(sozlar, key=len))
print("python:", sozlar.count("python"), "marta")
  1. harorat.csv faylini yarating (kun,harorat ustunlari, 5 kunlik maʼlumot) va csv moduli yordamida örtaça, eng yuqori va eng past haroratni çiqaring.
Yeçim
Python
import csv

with open("harorat.csv", "w", encoding="utf-8", newline="") as f:
    w = csv.writer(f)
    w.writerow(["kun", "harorat"])
    w.writerows([["Duşanba", 18], ["Seşanba", 21], ["Çorşanba", 25], ["Payşanba", 19], ["Juma", 23]])

with open("harorat.csv", encoding="utf-8", newline="") as f:
    qiymatlar = [int(q["harorat"]) for q in csv.DictReader(f)]

print(f"Örtaça: {sum(qiymatlar) / len(qiymatlar):.1f}°C")
print("Eng yuqori:", max(qiymatlar), "| Eng past:", min(qiymatlar))
  1. Kitob dökoni uçun ombor.json faylini yarating ({"kitob nomi": soni}). Söng faylni öqib, bitta kitobdan 2 dona soting (sonini kamaytiring) va faylni qayta saqlang. Oxirida yangilangan maʼlumotni çiqaring.
Yeçim
Python
import json
from pathlib import Path

fayl = Path("ombor.json")
fayl.write_text(json.dumps({"Ufq": 10, "Sariq devni minib": 4}, ensure_ascii=False), encoding="utf-8")

ombor = json.loads(fayl.read_text(encoding="utf-8"))
ombor["Ufq"] -= 2
fayl.write_text(json.dumps(ombor, ensure_ascii=False, indent=2), encoding="utf-8")

print(json.loads(fayl.read_text(encoding="utf-8")))
  1. Mavjud bölmagan faylni öqişga harakat qiladigan, lekin FileNotFoundError ni uşlab, "Fayl topilmadi, yangisi yaratildi" deb böş fayl yaratadigan xavfsiz_oqi(nom) funksiyasini yozing.
Yeçim
Python
from pathlib import Path


def xavfsiz_oqi(nom: str) -> str:
    try:
        return Path(nom).read_text(encoding="utf-8")
    except FileNotFoundError:
        Path(nom).write_text("", encoding="utf-8")
        print("Fayl topilmadi, yangisi yaratildi.")
        return ""


matn = xavfsiz_oqi("eslatmalar.txt")
print("Uzunligi:", len(matn), "| Endi bormi?", Path("eslatmalar.txt").exists())