csv --- CSV Đọc và ghi tệp

Source code: Lib/csv.py


Định dạng được gọi là CSV (Giá trị được phân tách bằng dấu phẩy) là định dạng nhập và xuất phổ biến nhất cho bảng tính và cơ sở dữ liệu. Định dạng CSV đã được sử dụng trong nhiều năm trước khi cố gắng mô tả định dạng này theo cách chuẩn hóa trong RFC 4180. Việc thiếu một tiêu chuẩn được xác định rõ ràng có nghĩa là những khác biệt nhỏ thường tồn tại trong dữ liệu được tạo ra và sử dụng bởi các ứng dụng khác nhau. Những khác biệt này có thể gây khó chịu khi xử lý tệp CSV từ nhiều nguồn. Tuy nhiên, mặc dù các dấu phân cách và ký tự trích dẫn khác nhau, định dạng tổng thể vẫn tương tự đến mức có thể viết một mô-đun duy nhất có thể thao tác dữ liệu đó một cách hiệu quả, ẩn các chi tiết đọc và ghi dữ liệu khỏi người lập trình.

Mô-đun csv triển khai các lớp để đọc và ghi dữ liệu dạng bảng ở định dạng CSV. Nó cho phép các lập trình viên nói, "ghi dữ liệu này ở định dạng mà Excel ưa thích" hoặc "đọc dữ liệu từ tệp này do Excel tạo ra" mà không biết chi tiết chính xác về định dạng CSV được Excel sử dụng. Các lập trình viên cũng có thể mô tả các định dạng CSV được các ứng dụng khác hiểu hoặc xác định các định dạng CSV cho mục đích đặc biệt của riêng họ.

Các đối tượng readerwriter của mô-đun csv đọc và ghi các chuỗi. Các lập trình viên cũng có thể đọc và ghi dữ liệu ở dạng từ điển bằng cách sử dụng các lớp DictReaderDictWriter.

Xem thêm

PEP 305 - CSV Tập tin API

Đề xuất cải tiến Python đề xuất bổ sung này cho Python.

Nội dung mô-đun

Mô-đun csv xác định các chức năng sau:

csv.reader(csvfile, /, dialect='excel', **fmtparams)

Trả về một reader object sẽ xử lý các dòng từ csvfile đã cho. Tệp csvfile phải là một chuỗi có thể lặp lại, mỗi chuỗi có định dạng csv do người đọc xác định. Tệp csvfile thường là một đối tượng hoặc danh sách giống như tệp. Nếu csvfile là một đối tượng tệp, nó sẽ được mở bằng newline=''. [1] Một tham số dialect tùy chọn có thể được cung cấp để xác định một tập hợp các tham số cụ thể cho một phương ngữ CSV cụ thể. Nó có thể là một thể hiện của một lớp con của lớp Dialect hoặc một trong các chuỗi được hàm list_dialects() trả về. Các đối số từ khóa fmtparams tùy chọn khác có thể được cung cấp để ghi đè các tham số định dạng riêng lẻ trong phương ngữ hiện tại. Để biết chi tiết đầy đủ về các tham số định dạng và phương ngữ, hãy xem phần Các tham số phương ngữ và định dạng.

Mỗi hàng đọc từ tệp csv sẽ được trả về dưới dạng danh sách các chuỗi. Không có chuyển đổi loại dữ liệu tự động nào được thực hiện trừ khi tùy chọn định dạng QUOTE_NONNUMERIC được chỉ định (trong trường hợp đó các trường không trích dẫn sẽ được chuyển thành số float).

Một ví dụ sử dụng ngắn:

>>> nhập csv
>>> với open('eggs.csv', newline='') dưới dạng csvfile:
... spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
... cho hàng trong spamreader:
... print(', '.join(row))
Thư rác, Thư rác, Thư rác, Thư rác, Thư rác, Đậu nướng
Thư rác, Thư rác đáng yêu, Thư rác tuyệt vời
csv.writer(csvfile, /, dialect='excel', **fmtparams)

Trả về đối tượng writer chịu trách nhiệm chuyển đổi dữ liệu của người dùng thành các chuỗi được phân tách trên đối tượng giống như tệp đã cho. csvfile có thể là bất kỳ đối tượng nào có phương thức write(). Nếu csvfile là một đối tượng tệp, nó sẽ được mở bằng newline='' [1]. Một tham số dialect tùy chọn có thể được cung cấp để xác định một tập hợp các tham số cụ thể cho một phương ngữ CSV cụ thể. Nó có thể là một thể hiện của một lớp con của lớp Dialect hoặc một trong các chuỗi được hàm list_dialects() trả về. Các đối số từ khóa fmtparams tùy chọn khác có thể được cung cấp để ghi đè các tham số định dạng riêng lẻ trong phương ngữ hiện tại. Để biết chi tiết đầy đủ về các phương ngữ và tham số định dạng, hãy xem phần Các tham số phương ngữ và định dạng. Để giúp giao tiếp với các mô-đun triển khai DB API dễ dàng nhất có thể, giá trị None được viết dưới dạng chuỗi trống. Mặc dù đây không phải là một phép chuyển đổi có thể đảo ngược nhưng nó giúp chuyển các giá trị dữ liệu SQL NULL sang tệp CSV mà không cần xử lý trước dữ liệu được trả về từ lệnh gọi cursor.fetch*. Tất cả dữ liệu không phải chuỗi khác đều được xâu chuỗi bằng str() trước khi được ghi.

Một ví dụ sử dụng ngắn:

nhập csv
với open('eggs.csv', 'w', newline='')  csvfile:
    người viết thư rác = csv.writer(csvfile, delimiter=' ',
                            quotechar='|', trích dẫn=csv.QUOTE_MINIMAL)
    spamwriter.writerow(['Spam'] * 5 + ['Đậu nướng'])
    spamwriter.writerow(['Thư rác', 'Thư rác đáng yêu', 'Thư rác tuyệt vời'])
csv.register_dialect(name, /, dialect='excel', **fmtparams)

Liên kết dialect với name. name phải là một chuỗi. Phương ngữ có thể được chỉ định bằng cách chuyển một lớp con của Dialect hoặc bằng các đối số từ khóa fmtparams hoặc cả hai, với các đối số từ khóa ghi đè các tham số của phương ngữ. Để biết chi tiết đầy đủ về các phương ngữ và tham số định dạng, hãy xem phần Các tham số phương ngữ và định dạng.

csv.unregister_dialect(name)

Xóa phương ngữ được liên kết với name khỏi sổ đăng ký phương ngữ. Một Error được nêu ra nếu name không phải là tên phương ngữ đã đăng ký.

csv.get_dialect(name)

Trả về phương ngữ được liên kết với name. Một Error được nêu ra nếu name không phải là tên phương ngữ đã đăng ký. Hàm này trả về một Dialect bất biến.

csv.list_dialects()

Trả lại tên của tất cả các phương ngữ đã đăng ký.

csv.field_size_limit()
csv.field_size_limit(new_limit)

Trả về kích thước trường tối đa hiện tại được trình phân tích cú pháp cho phép. Nếu new_limit được đưa ra, đây sẽ trở thành giới hạn mới.

Mô-đun csv xác định các lớp sau:

class csv.DictReader(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)

Tạo một đối tượng hoạt động giống như một trình đọc thông thường nhưng ánh xạ thông tin trong mỗi hàng tới một dict có khóa được cung cấp bởi tham số fieldnames tùy chọn.

Tham số fieldnamessequence. Nếu fieldnames bị bỏ qua, các giá trị ở hàng đầu tiên của tệp f sẽ được sử dụng làm tên trường và sẽ bị loại bỏ khỏi kết quả. Nếu fieldnames được cung cấp, chúng sẽ được sử dụng và hàng đầu tiên sẽ được đưa vào kết quả. Bất kể tên trường được xác định như thế nào, từ điển vẫn giữ nguyên thứ tự ban đầu của chúng.

Nếu một hàng có nhiều trường hơn tên trường thì dữ liệu còn lại sẽ được đưa vào danh sách và được lưu trữ với tên trường được chỉ định bởi restkey (mặc định là None). Nếu một hàng không trống có ít trường hơn tên trường thì các giá trị còn thiếu sẽ được điền bằng giá trị restval (mặc định là None).

Tất cả các đối số từ khóa hoặc tùy chọn khác được chuyển đến phiên bản reader cơ bản.

Nếu đối số được truyền cho fieldnames là một iterator, thì nó sẽ bị ép buộc thành list.

Thay đổi trong phiên bản 3.6: Các hàng trả về hiện thuộc loại OrderedDict.

Thay đổi trong phiên bản 3.8: Các hàng trả về hiện thuộc loại dict.

Một ví dụ sử dụng ngắn:

>>> nhập csv
>>> với open('names.csv', newline='')  csvfile:
... reader = csv.DictReader(csvfile)
... cho hàng trong trình đọc:
... print(row['first_name'], row['last_name'])
...
Eric nhàn rỗi
John Cleese

>>> in (hàng)
{'first_name': 'John', 'last_name': 'Cleese'}
class csv.DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)

Tạo một đối tượng hoạt động giống như một trình soạn thảo thông thường nhưng ánh xạ các từ điển vào các hàng đầu ra. Tham số fieldnames là một sequence các khóa xác định thứ tự các giá trị trong từ điển được truyền cho phương thức writerow() được ghi vào tệp f. Tham số restval tùy chọn chỉ định giá trị được ghi nếu từ điển thiếu khóa trong fieldnames. Nếu từ điển được truyền cho phương thức writerow() chứa khóa không được tìm thấy trong fieldnames, thì tham số extrasaction tùy chọn sẽ cho biết hành động cần thực hiện. Nếu nó được đặt thành 'raise', giá trị mặc định, ValueError sẽ được nâng lên. Nếu nó được đặt thành 'ignore', các giá trị bổ sung trong từ điển sẽ bị bỏ qua. Bất kỳ đối số từ khóa hoặc tùy chọn nào khác đều được chuyển đến phiên bản writer cơ bản.

Lưu ý rằng không giống như lớp DictReader, tham số fieldnames của lớp DictWriter không phải là tùy chọn.

Nếu đối số được truyền cho fieldnames là một iterator, thì nó sẽ bị ép buộc thành list.

Một ví dụ sử dụng ngắn:

nhập csv

với open('names.csv', 'w', newline='')  csvfile:
    tên trường = ['first_name', 'last_name']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    nhà văn.writeheader()
    writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
    writer.writerow({'first_name': 'Đáng yêu', 'last_name': 'Spam'})
    writer.writerow({'first_name': 'Tuyệt vời', 'last_name': 'Spam'})
class csv.Dialect

Lớp Dialect là một lớp chứa có các thuộc tính chứa thông tin về cách xử lý dấu ngoặc kép, khoảng trắng, dấu phân cách, v.v. Do thiếu thông số kỹ thuật CSV nghiêm ngặt, các ứng dụng khác nhau sẽ tạo ra dữ liệu CSV khác nhau một cách tinh vi. Các phiên bản Dialect xác định cách hoạt động của các phiên bản readerwriter.

Tất cả các tên Dialect có sẵn đều được trả về bởi list_dialects() và chúng có thể được đăng ký với các lớp readerwriter cụ thể thông qua các hàm khởi tạo (__init__) như sau:

nhập csv

với open('students.csv', 'w', newline='')  csvfile:
    nhà văn = csv.writer(csvfile, phương ngữ='unix')
class csv.excel

Lớp excel xác định các thuộc tính thông thường của tệp CSV do Excel tạo. Nó được đăng ký với tên phương ngữ 'excel'.

class csv.excel_tab

Lớp excel_tab xác định các thuộc tính thông thường của tệp được phân tách bằng TAB do Excel tạo. Nó được đăng ký với tên phương ngữ 'excel-tab'.

class csv.unix_dialect

Lớp unix_dialect xác định các thuộc tính thông thường của tệp CSV được tạo trên hệ thống UNIX, tức là sử dụng '\n' làm dấu kết thúc dòng và trích dẫn tất cả các trường. Nó được đăng ký với tên phương ngữ 'unix'.

Added in version 3.2.

class csv.Sniffer

Lớp Sniffer được sử dụng để suy ra định dạng của tệp CSV.

Lớp Sniffer cung cấp hai phương thức:

sniff(sample, delimiters=None)

Phân tích sample đã cho và trả về lớp con Dialect phản ánh các tham số được tìm thấy. Nếu tham số delimiters tùy chọn được đưa ra, nó được hiểu là một chuỗi chứa các ký tự phân cách hợp lệ có thể có.

has_header(sample)

Phân tích văn bản mẫu (được cho là ở định dạng CSV) và trả về True nếu hàng đầu tiên xuất hiện là một chuỗi tiêu đề cột. Kiểm tra từng cột, một trong hai tiêu chí chính sẽ được xem xét để ước tính xem mẫu có chứa tiêu đề hay không:

  • hàng thứ hai đến thứ n chứa các giá trị số

  • hàng thứ hai đến thứ n chứa các chuỗi trong đó độ dài của ít nhất một giá trị khác với độ dài của tiêu đề giả định của cột đó.

21 hàng sau tiêu đề được lấy mẫu; nếu hơn một nửa số cột + hàng đáp ứng tiêu chí, True sẽ được trả về.

Ghi chú

Phương pháp này là một phương pháp phỏng đoán thô và có thể tạo ra cả kết quả dương tính giả và âm tính giả.

Một ví dụ cho Sniffer sử dụng

với open('example.csv', newline='')  csvfile:
    phương ngữ = csv.Sniffer().sniff(csvfile.read(1024))
    csvfile.seek(0)
    reader = csv.reader(csvfile, phương ngữ)
    # ... xử lý nội dung file CSV tại đây ...

Mô-đun csv xác định các hằng số sau:

csv.QUOTE_ALL

Hướng dẫn các đối tượng writer trích dẫn tất cả các trường.

csv.QUOTE_MINIMAL

Hướng dẫn các đối tượng writer chỉ trích dẫn những trường chứa các ký tự đặc biệt như delimiter, quotechar, '\r', '\n' hoặc bất kỳ ký tự nào trong lineterminator.

csv.QUOTE_NONNUMERIC

Hướng dẫn các đối tượng writer trích dẫn tất cả các trường không phải là số.

Hướng dẫn các đối tượng reader chuyển đổi tất cả các trường không có dấu ngoặc kép sang loại float.

Ghi chú

Một số loại số, chẳng hạn như bool, Fraction hoặc IntEnum, có biểu diễn chuỗi không thể chuyển đổi thành float. Chúng không thể được đọc ở chế độ QUOTE_NONNUMERICQUOTE_STRINGS.

csv.QUOTE_NONE

Hướng dẫn các đối tượng writer không bao giờ trích dẫn các trường. Khi delimiter, quotechar, escapechar, '\r', '\n' hiện tại hoặc bất kỳ ký tự nào trong lineterminator xuất hiện trong dữ liệu đầu ra, nó sẽ đứng trước ký tự escapechar hiện tại. Nếu escapechar không được đặt, người viết sẽ tăng Error nếu gặp bất kỳ ký tự nào yêu cầu thoát. Đặt quotechar thành None để ngăn nó thoát.

Hướng dẫn các đối tượng reader không thực hiện xử lý đặc biệt các ký tự trích dẫn.

csv.QUOTE_NOTNULL

Hướng dẫn các đối tượng writer trích dẫn tất cả các trường không phải là None. Điều này tương tự như QUOTE_ALL, ngoại trừ việc nếu giá trị trường là None thì một chuỗi trống (không trích dẫn) sẽ được ghi.

Hướng dẫn các đối tượng reader diễn giải một trường trống (không có trích dẫn) là None và hoạt động như QUOTE_ALL.

Added in version 3.12.

csv.QUOTE_STRINGS

Hướng dẫn các đối tượng writer luôn đặt dấu ngoặc kép xung quanh các trường là chuỗi. Điều này tương tự như QUOTE_NONNUMERIC, ngoại trừ việc nếu giá trị trường là None thì một chuỗi trống (không trích dẫn) sẽ được ghi.

Hướng dẫn các đối tượng reader diễn giải một chuỗi trống (không có trích dẫn) là None và hoạt động như QUOTE_NONNUMERIC.

Added in version 3.12.

Mô-đun csv xác định ngoại lệ sau:

exception csv.Error

Được tăng lên bởi bất kỳ chức năng nào khi phát hiện ra lỗi.

Các tham số phương ngữ và định dạng

Để dễ dàng chỉ định định dạng của bản ghi đầu vào và đầu ra, các tham số định dạng cụ thể được nhóm lại với nhau thành các phương ngữ. Một phương ngữ là một lớp con của lớp Dialect chứa nhiều thuộc tính khác nhau mô tả định dạng của tệp CSV. Khi tạo các đối tượng reader hoặc writer, lập trình viên có thể chỉ định một chuỗi hoặc một lớp con của lớp Dialect làm tham số phương ngữ. Ngoài hoặc thay vì tham số dialect, lập trình viên cũng có thể chỉ định các tham số định dạng riêng lẻ có cùng tên với các thuộc tính được xác định bên dưới cho lớp Dialect.

Các phương ngữ hỗ trợ các thuộc tính sau:

Dialect.delimiter

Chuỗi một ký tự dùng để phân tách các trường. Nó mặc định là ','.

Dialect.doublequote

Kiểm soát cách các phiên bản quotechar xuất hiện bên trong một trường sẽ được trích dẫn. Khi True, ký tự được nhân đôi. Khi False, escapechar được sử dụng làm tiền tố cho quotechar. Nó mặc định là True.

Ở đầu ra, nếu doublequoteFalse và không có escapechar nào được đặt, Error sẽ được nâng lên nếu tìm thấy quotechar trong một trường.

Dialect.escapechar

Chuỗi một ký tự được người viết sử dụng để thoát các ký tự cần thoát:

  • delimiter, quotechar, '\r', '\n' và bất kỳ ký tự nào trong lineterminator đều được thoát nếu quoting được đặt thành QUOTE_NONE;

  • quotechar bị thoát nếu doublequoteFalse;

  • chính escapechar.

Khi đọc, escapechar sẽ loại bỏ mọi ý nghĩa đặc biệt khỏi ký tự sau. Nó mặc định là None, vô hiệu hóa việc thoát.

Thay đổi trong phiên bản 3.11: Không được phép escapechar trống.

Dialect.lineterminator

Chuỗi được sử dụng để kết thúc các dòng do writer tạo ra. Nó mặc định là '\r\n'.

Ghi chú

reader được mã hóa cứng để nhận ra '\r' hoặc '\n' là cuối dòng và bỏ qua lineterminator. Hành vi này có thể thay đổi trong tương lai.

Dialect.quotechar

Chuỗi một ký tự được sử dụng để trích dẫn các trường chứa các ký tự đặc biệt, chẳng hạn như delimiter hoặc quotechar hoặc chứa các ký tự dòng mới ('\r', '\n' hoặc bất kỳ ký tự nào trong lineterminator). Nó mặc định là '"'. Có thể được đặt thành None để tránh thoát '"' nếu quoting được đặt thành QUOTE_NONE.

Thay đổi trong phiên bản 3.11: Không được phép quotechar trống.

Dialect.quoting

Kiểm soát thời điểm người viết phải tạo dấu ngoặc kép và được người đọc nhận ra. Nó có thể nhận bất kỳ QUOTE_* constants nào và mặc định là QUOTE_MINIMAL nếu quotechar không phải là NoneQUOTE_NONE nếu không.

Dialect.skipinitialspace

Khi True, các khoảng trắng ngay sau delimiter sẽ bị bỏ qua. Mặc định là False. Khi kết hợp delimiter=' ' với skipinitialspace=True, các trường trống không được trích dẫn sẽ không được phép.

Dialect.strict

Khi True, đưa ra ngoại lệ Error trên đầu vào CSV sai. Mặc định là False.

Đối tượng đọc

Các đối tượng Reader (các phiên bản DictReader và các đối tượng được hàm reader() trả về) có các phương thức công khai sau:

csvreader.__next__()

Trả về hàng tiếp theo của đối tượng có thể lặp của trình đọc dưới dạng danh sách (nếu đối tượng được trả về từ reader()) hoặc một lệnh (nếu đó là phiên bản DictReader), được phân tích cú pháp theo Dialect hiện tại. Thông thường bạn nên gọi đây là next(reader).

Đối tượng Reader có các thuộc tính công khai sau:

csvreader.dialect

Mô tả chỉ đọc về phương ngữ được trình phân tích cú pháp sử dụng.

csvreader.line_num

Số dòng được đọc từ trình vòng lặp nguồn. Giá trị này không giống với số lượng bản ghi được trả về vì các bản ghi có thể trải dài trên nhiều dòng.

Các đối tượng DictReader có thuộc tính public sau:

DictReader.fieldnames

Nếu không được truyền dưới dạng tham số khi tạo đối tượng, thuộc tính này sẽ được khởi tạo khi truy cập lần đầu hoặc khi bản ghi đầu tiên được đọc từ tệp.

Đối tượng nhà văn

Các đối tượng writer (các phiên bản DictWriter và các đối tượng được hàm writer() trả về) có các phương thức công khai sau. Một row phải là một chuỗi hoặc số có thể lặp lại cho các đối tượng writer và một từ điển ánh xạ tên trường thành chuỗi hoặc số (bằng cách chuyển chúng qua str() trước) cho các đối tượng DictWriter. Lưu ý rằng số phức được viết ra bao quanh bởi dấu ngoặc đơn. Điều này có thể gây ra một số vấn đề cho các chương trình khác đọc tệp CSV (giả sử chúng hỗ trợ số phức).

csvwriter.writerow(row, /)

Viết tham số row vào đối tượng file của người viết, được định dạng theo Dialect hiện tại. Trả về giá trị trả về của lệnh gọi tới phương thức write của đối tượng tệp cơ bản.

Thay đổi trong phiên bản 3.5: Đã thêm hỗ trợ cho các lần lặp tùy ý.

csvwriter.writerows(rows, /)

Viết tất cả các phần tử trong rows (một đối tượng có thể lặp lại của row như được mô tả ở trên) vào đối tượng tệp của người viết, được định dạng theo phương ngữ hiện tại.

Đối tượng Writer có thuộc tính public sau:

csvwriter.dialect

Mô tả chỉ đọc về phương ngữ được người viết sử dụng.

Các đối tượng DictWriter có phương thức công khai sau:

DictWriter.writeheader()

Viết một hàng có tên trường (như được chỉ định trong hàm tạo) vào đối tượng tệp của người viết, được định dạng theo phương ngữ hiện tại. Trả về giá trị trả về của lệnh gọi csvwriter.writerow() được sử dụng nội bộ.

Added in version 3.2.

Thay đổi trong phiên bản 3.8: writeheader() hiện cũng trả về giá trị được trả về bởi phương thức csvwriter.writerow() mà nó sử dụng nội bộ.

Ví dụ

Ví dụ đơn giản nhất về đọc tệp CSV:

nhập csv
với open('some.csv', newline='')  f:
    reader = csv.reader(f)
    cho hàng trong trình đọc:
        in (hàng)

Đọc tệp có định dạng thay thế:

nhập csv
với open('passwd', newline='')  f:
    reader = csv.reader(f, delimiter=':', quote=csv.QUOTE_NONE)
    cho hàng trong trình đọc:
        in (hàng)

Ví dụ viết đơn giản nhất có thể tương ứng là:

nhập csv
với open('some.csv', 'w', newline='')  f:
    nhà văn = csv.writer(f)
    writer.writerows(someiterable)

open() được sử dụng để mở tệp CSV để đọc nên theo mặc định, tệp sẽ được giải mã thành unicode bằng cách sử dụng mã hóa mặc định của hệ thống (xem locale.getencoding()). Để giải mã một tệp bằng cách mã hóa khác, hãy sử dụng đối số encoding của open:

nhập csv
với open('some.csv', newline='',coding='utf-8')  f:
    reader = csv.reader(f)
    cho hàng trong trình đọc:
        in (hàng)

Điều tương tự cũng áp dụng cho việc ghi bằng thứ gì đó không phải là mã hóa mặc định của hệ thống: chỉ định đối số mã hóa khi mở tệp đầu ra.

Đăng ký một phương ngữ mới:

nhập csv
csv.register_dialect('unixpwd', delimiter=':', quote=csv.QUOTE_NONE)
với open('passwd', newline='')  f:
    reader = csv.reader(f, 'unixpwd')

Cách sử dụng trình đọc nâng cao hơn một chút --- bắt và báo cáo lỗi:

nhập csv, sys
tên tệp = 'some.csv'
với open(filename, newline='')  f:
    reader = csv.reader(f)
    thử:
        cho hàng trong trình đọc:
            in (hàng)
    ngoại trừ csv.Error  e:
        sys.exit(f'file {filename}, dòng {reader.line_num}: {e}')

Và mặc dù mô-đun không hỗ trợ trực tiếp các chuỗi phân tích cú pháp, nhưng nó có thể được thực hiện dễ dàng

nhập csv
cho hàng trong csv.reader(['one,two, three']):
    in (hàng)

Chú thích cuối trang