งูสีเขียวต้นฉบับกำลังดมตัวอย่างริบบิ้นข้อมูลแล้วแยกลงถาดเครื่องหมายคั่นสองแบบ

Python csv.Sniffer: เดารูปแบบไฟล์ได้ แต่ต้องมี fallback ที่คาดเดาได้

พี่โชว์Engineering

ไฟล์ที่ผู้ใช้เรียก CSV อาจคั่นด้วย comma, semicolon หรือ tab ครับ csv.Sniffer ดู sample แล้วคืน dialect ที่น่าจะใช่ ช่วยลดหน้าตั้งค่า แต่เอกสารย้ำว่าการเดา header และ dialect เป็น heuristic จึงอาจให้ผลบวกหรือลบผิด

import csv
import io
import unittest


def read_rows(text: str, fallback: str = ",") -> list[list[str]]:
    sample = text[:4096]
    try:
        dialect = csv.Sniffer().sniff(sample, delimiters=",;\t")
    except csv.Error:
        dialect = csv.excel
        dialect.delimiter = fallback
    return list(csv.reader(io.StringIO(text), dialect))


class SnifferTests(unittest.TestCase):
    def test_semicolon(self):
        self.assertEqual(read_rows("name;score\nAda;9\n"), [["name", "score"], ["Ada", "9"]])

    def test_ambiguous_sample_uses_fallback(self):
        self.assertEqual(read_rows("single\n"), [["single"]])


if __name__ == "__main__":
    unittest.main()

จำกัด delimiters ให้เหลือชุดที่ระบบรองรับจริง ไม่เช่นนั้นอักขระที่เกิดบ่อยในข้อความอาจถูกเดาเป็นตัวคั่น อ่าน sample แบบมีเพดานเพื่อไม่ให้ไฟล์ใหญ่กิน memory และอย่าถือ has_header() เป็นหลักฐาน schema ให้ validate จำนวนคอลัมน์ ชื่อ field และชนิดข้อมูลหลัง parse เสมอ

Recap

  • จำกัด delimiter ที่ยอมรับ
  • กำหนดขนาด sample และ fallback
  • แยก “เดารูปแบบ” ออกจาก “ยืนยัน schema”
  • ทดสอบไฟล์สั้น กำกวม และแถวคอลัมน์ไม่ครบ