Asosiy qismga o'tish

Matnli fayllar (txt)

19-bob 21 kod bloki 2177 so'z

Bu bobda

  • faylga yozishni va fayldan o'qishni
  • with open(...) nima uchun kerakligini
  • "r", "w", "a" rejimlari farqini (va "w" tuzog'ini)
  • encoding="utf-8" nega o'zbekcha matn uchun majburiy ekanini
  • fayldagi ma'lumotni qayta ishlab, hisobot yozishni

Nega fayl kerak?

Dastur yopilganda o'zgaruvchilar xotiradan o'chib ketadi. Natijani saqlab qo'yish, keyingi safar davom ettirish yoki boshqa dasturga berish uchun ma'lumotni faylga yozish kerak. Eng oddiy format — oddiy matnli fayl (.txt).

Faylga yozish

sql4 qator
with open("salom.txt", "w", encoding="utf-8") as f:
    f.write("Salom, fayl!\n")
    f.write("Bu ikkinchi qator.\n")
print("Yozildi")
Natija
Yozildi
  • open(nom, rejim, encoding=...) — faylni ochadi va fayl obyektini qaytaradi.
  • "w" — yozish (write) rejimi.
  • with ... as f: — blok tugaganda faylni avtomatik yopadi, hatto ichkarida xato bo'lsa ham.
  • f.write() yangi qatorga o'zi o'tmaydi — \n ni o'zingiz yozasiz.

Fayl daftar turgan papkada paydo bo'ladi. Jupyterning chap panelida uni ochib ko'rishingiz mumkin.

Fayldan o'qish

sql3 qator
with open("salom.txt", encoding="utf-8") as f:
    matn = f.read()
print(matn)
Natija
Salom, fayl!
Bu ikkinchi qator.

Rejim berilmasa — "r" (o'qish). read() butun faylni bitta satr qilib beradi.

Qatorma-qator o'qish uchun fayl obyekti bo'ylab for:

sql3 qator
with open("salom.txt", encoding="utf-8") as f:
    for qator in f:
        print(repr(qator))
Natija
'Salom, fayl!\n'
'Bu ikkinchi qator.\n'

Har bir qator oxirida \n bor. print() ham o'zidan \n qo'shadi, shuning uchun qatorlar orasida bo'sh qator paydo bo'ladi. rstrip() bilan olib tashlaymiz:

sql3 qator
with open("salom.txt", encoding="utf-8") as f:
    for qator in f:
        print(qator.rstrip())
Natija
Salom, fayl!
Bu ikkinchi qator.

readlines() — barcha qatorlarni ro'yxat qilib beradi:

sql4 qator
with open("salom.txt", encoding="utf-8") as f:
    qatorlar = f.readlines()
print(qatorlar)
print(len(qatorlar), "qator")
Natija
['Salom, fayl!\n', 'Bu ikkinchi qator.\n']
2 qator

Rejimlar

Rejim Ma'nosi Fayl yo'q bo'lsa Fayl bor bo'lsa
"r" o'qish FileNotFoundError o'qiydi
"w" yozish yaratadi ichini o'chirib, boshidan yozadi
"a" qo'shish (append) yaratadi oxiriga qo'shadi
"x" faqat yangi fayl yaratadi FileExistsError

"w" eski ma'lumotni o'chirib yuboradi

sql6 qator
with open("kundalik.txt", "w", encoding="utf-8") as f:
    f.write("1-kun: Python o'rnatdim\n")
with open("kundalik.txt", "w", encoding="utf-8") as f:
    f.write("2-kun: o'zgaruvchilarni o'rgandim\n")
with open("kundalik.txt", encoding="utf-8") as f:
    print(f.read())
Natija
2-kun: o'zgaruvchilarni o'rgandim

1-kun yo'qoldi! "w" faylni har safar bo'shatadi. Yozuv qo'shish uchun "a":

sql5 qator
with open("kundalik.txt", "a", encoding="utf-8") as f:
    f.write("3-kun: shartlarni o'rgandim\n")
    f.write("4-kun: sikllarni o'rgandim\n")
with open("kundalik.txt", encoding="utf-8") as f:
    print(f.read())
Natija
2-kun: o'zgaruvchilarni o'rgandim
3-kun: shartlarni o'rgandim
4-kun: sikllarni o'rgandim

encoding ni unutish

Windows da open() standart holatda o'zbekcha va ruscha harflarni har doim ham to'g'ri o'qimaydi: ʻ, ғ, ў kabi belgilar o'rnida g'alati belgilar chiqadi yoki UnicodeDecodeError bo'ladi. Fayl boshqa kompyuterda ochilganda muammo chiqadi. Qoida: matnli faylni doim encoding="utf-8" bilan oching — yozganda ham, o'qiganda ham.

write() faqat satr qabul qiladi:

sql2 qator
with open("son.txt", "w", encoding="utf-8") as f:
    f.write(42)
Xato xabari
TypeError: write() argument must be str, not int

Sonni yozishdan oldin satrga o'giring: f.write(str(42)) yoki f.write(f"{42}\n"). O'qiganda esa qaytadan int() qilasiz (2-bobdagi input() bilan bir xil holat).

Misol: π ning raqamlari

Python Crash Course dagi mashhur misol. Avval faylni yaratamiz:

Fayl: pi_raqamlar.txt

python3 qator
3.1415926535
  8979323846
  2643383279
sql8 qator
with open("pi_raqamlar.txt", encoding="utf-8") as f:
    qatorlar = f.readlines()

pi = ""
for qator in qatorlar:
    pi += qator.strip()
print(pi)
print(len(pi), "belgi")
Natija
3.141592653589793238462643383279
32 belgi

strip() (ikki tomondan) ishlatdik, chunki 2- va 3-qatorlar boshida ham probel bor. Faqat rstrip() qilsak, ular satr ichida qolib ketardi.

Endi kattaroq fayl: π ning 1000 ta raqami. Uni qo'lda yozmaymiz — hisoblab, faylga yozamiz. Quyidagi katakdagi hisoblash usulini (Machin formulasi) tushunish shart emas, muhimi — natija faylga qanday yozilishi:

python20 qator
def pi_raqamlari(n):
    def arctan(x, bir):
        s = t = bir // x
        k, ishora = 1, -1
        while t:
            t //= x * x
            k += 2
            s += ishora * (t // k)
            ishora = -ishora
        return s
    bir = 10 ** (n + 10)
    return str(4 * (4 * arctan(5, bir) - arctan(239, bir)) // 10 ** 10)


raqamlar = pi_raqamlari(1000)
with open("pi_1000.txt", "w", encoding="utf-8") as f:
    f.write("3.\n")
    for i in range(1, len(raqamlar), 50):
        f.write(raqamlar[i:i + 50] + "\n")
print("pi_1000.txt yozildi")
Natija
pi_1000.txt yozildi

Fayl 50 tadan raqamli qatorlarga bo'lingan. O'qib, bitta satrga yig'amiz va tug'ilgan kunni qidiramiz:

sql10 qator
with open("pi_1000.txt", encoding="utf-8") as f:
    pi = "".join(qator.strip() for qator in f)
print(pi[:52] + "...")
print(len(pi), "belgi")

tugilgan = input("Tug'ilgan kuningiz (kkooyy): ")
if tugilgan in pi:
    print(f"Tug'ilgan kuningiz π ning birinchi 1000 raqami ichida bor! O'rni: {pi.find(tugilgan)}")
else:
    print("Birinchi 1000 raqamda yo'q.")
Natija
3.14159265358979323846264338327950288419716939937510...
1002 belgi
Tug'ilgan kuningiz (kkooyy): 120190
Tug'ilgan kuningiz π ning birinchi 1000 raqami ichida bor! O'rni: 244

"".join(... for qator in f) — 12-bobdagi comprehension ning qavssiz shakli, join ga to'g'ridan-to'g'ri beriladi. 6 xonali sana 1000 raqam ichida chiqish ehtimoli kichik, lekin ba'zilariga omad kulib boqadi.

Misol: fayldagi ma'lumotdan hisobot

Fayllar ko'pincha jadval ko'rinishidagi ma'lumot saqlaydi — har qatorda bitta yozuv, qismlari vergul bilan:

Fayl: ballar.txt

matn5 qator
Ali,78
Sarvinoz,91
Otabek,85
Javohir,59
Behruz,72

O'qiymiz, hisoblaymiz va natijani yangi faylga yozamiz:

python18 qator
talabalar = []
with open("ballar.txt", encoding="utf-8") as f:
    for qator in f:
        ism, ball = qator.strip().split(",")
        talabalar.append((ism, int(ball)))

ortacha = sum(b for _, b in talabalar) / len(talabalar)

with open("hisobot.txt", "w", encoding="utf-8") as f:
    f.write(f"Talabalar soni: {len(talabalar)}\n")
    f.write(f"O'rtacha ball: {ortacha:.1f}\n")
    f.write("-" * 24 + "\n")
    for ism, ball in sorted(talabalar, key=lambda t: t[1], reverse=True):
        holat = "o'tdi" if ball >= 60 else "qayta"
        f.write(f"{ism:<10}{ball:>4}  {holat}\n")

with open("hisobot.txt", encoding="utf-8") as f:
    print(f.read())
Natija
Talabalar soni: 5
O'rtacha ball: 77.0
------------------------
Sarvinoz    91  o'tdi
Otabek      85  o'tdi
Ali         78  o'tdi
Behruz      72  o'tdi
Javohir     59  qayta

for _, b in talabalar — _ "bu qiymat kerak emas" degani (7-bob).

Misol: matndagi so'zlarni sanash

Fayl: hikoya.txt

matn2 qator
Bir bor ekan, bir yo'q ekan. Bir qishloqda bir dehqon yashar ekan.
Dehqonning bir bog'i bor ekan. Bog'da olma, anor va behi o'sar ekan.
sql12 qator
with open("hikoya.txt", encoding="utf-8") as f:
    matn = f.read()

sozlar = matn.lower().replace(".", "").replace(",", "").split()
sanoq = {}
for s in sozlar:
    sanoq[s] = sanoq.get(s, 0) + 1

print("Jami so'z:", len(sozlar))
print("Har xil so'z:", len(sanoq))
for soz in sorted(sanoq, key=sanoq.get, reverse=True)[:3]:
    print(soz, sanoq[soz])
Natija
Jami so'z: 24
Har xil so'z: 15
bir 5
ekan 5
bor 2

pathlib: qisqa yo'l

Kichik fayllar uchun pathlib.Path ning ikki metodi with open ni qisqartiradi:

python6 qator
from pathlib import Path

p = Path("qisqa.txt")
p.write_text("Bir qatorda yozish\nva o'qish\n", encoding="utf-8")
print(p.read_text(encoding="utf-8"))
print(p.exists(), Path("yoq.txt").exists())
Natija
Bir qatorda yozish
va o'qish

True False

Kitoblarda

  • Python asoslari: fayllar bilan ishlash 88–91-betlar.
  • Python Crash Course: 10-bob, Reading from a File 184–191-betlar (pi_digits.txt, Is Your Birthday Contained in Pi? 190-bet), Writing to a File 191–193-betlar.

Xulosa

  • with open(nom, rejim, encoding="utf-8") as f: — fayl blok oxirida o'zi yopiladi.
  • "r" o'qish, "w" yozish (eski matn o'chadi), "a" oxiriga qo'shish.
  • f.read() — hammasi, for qator in f — qatorma-qator, rstrip()/strip() bilan \n ni olib tashlang.
  • write() faqat satr oladi va \n ni o'zi qo'ymaydi.
  • O'zbekcha matn uchun encoding="utf-8" — doim.

Mashqlar

Har bir mashqda yechim avval faylni o'zi yaratadi, keyin uni o'qiydi.

19.1

Birinchi qatorda N, keyingi N qatorda matn berilgan. Qatorlarni matn.txt ga yozing, keyin fayldan o'qib, qatorlar sonini va eng uzun qatorni chiqaring.

KirishKutilgan natija
3, olma, tarvuz, nok3 tarvuz
1, Salom1 Salom
Yechimni ko'rish
python7 qator
n = int(input())
with open("matn.txt", "w", encoding="utf-8") as f:
    for _ in range(n):
        f.write(input() + "\n")
with open("matn.txt", encoding="utf-8") as f:
    qatorlar = [q.rstrip("\n") for q in f]
print(len(qatorlar), max(qatorlar, key=len))
19.2

Bitta qatorda sonlar berilgan. Ularni sonlar.txt ga har birini alohida qatorga yozing. Keyin faylni o'qib, sonlar yig'indisini chiqaring.

KirishKutilgan natija
5 12 724
100100
-3 3 1010
Yechimni ko'rish
sql5 qator
with open("sonlar.txt", "w", encoding="utf-8") as f:
    for s in input().split():
        f.write(s + "\n")
with open("sonlar.txt", encoding="utf-8") as f:
    print(sum(int(q) for q in f))
19.3

Ikkita qator berilgan. Birinchisini "w" bilan, ikkinchisini "a" bilan log.txt ga yozing. Keyin faylni o'qib, uning butun matnini chiqaring.

KirishKutilgan natija
Dastur ishga tushdi, Foydalanuvchi kirdiDastur ishga tushdi Foydalanuvchi kirdi
A, BA B
Yechimni ko'rish
sql6 qator
with open("log.txt", "w", encoding="utf-8") as f:
    f.write(input() + "\n")
with open("log.txt", "a", encoding="utf-8") as f:
    f.write(input() + "\n")
with open("log.txt", encoding="utf-8") as f:
    print(f.read().rstrip())
19.4

Birinchi qatorda N, keyingi N qatorda ism,ball berilgan. Ularni jurnal.txt ga yozing, keyin fayldan o'qib, 60 va undan yuqori ball olganlar ismlarini kiritilgan tartibda probel bilan chiqaring.

KirishKutilgan natija
4, Ali,78, Vali,45, Sarvinoz,91, Otabek,59Ali Sarvinoz
1, A,60A
Yechimni ko'rish
python11 qator
n = int(input())
with open("jurnal.txt", "w", encoding="utf-8") as f:
    for _ in range(n):
        f.write(input() + "\n")
otganlar = []
with open("jurnal.txt", encoding="utf-8") as f:
    for q in f:
        ism, ball = q.strip().split(",")
        if int(ball) >= 60:
            otganlar.append(ism)
print(" ".join(otganlar))

Bu bobni bepul o'qidingiz.

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

Telegramda yozish Narxlar