csv — CSV File Reading and Writing

Вихідний код: Lib/csv.py


Так званий формат CSV (значення, розділені комами) є найпоширенішим форматом імпорту та експорту для електронних таблиць і баз даних. Формат CSV використовувався протягом багатьох років до того, як його спробували описати стандартизованим способом у RFC 4180. Відсутність чітко визначеного стандарту означає, що часто існують тонкі відмінності в даних, які створюються та споживаються різними програмами. Ці відмінності можуть дратувати обробку файлів CSV із кількох джерел. Тим не менш, хоча розділювачі та символи лапок відрізняються, загальний формат досить схожий, щоб можна було написати один модуль, який може ефективно маніпулювати такими даними, приховуючи деталі читання та запису даних від програміста.

Модуль csv реалізує класи для читання та запису табличних даних у форматі CSV. Це дозволяє програмістам сказати: «записати ці дані у форматі, який віддає перевагу Excel» або «прочитати дані з цього файлу, створеного Excel», не знаючи точних деталей формату CSV, який використовує Excel. Програмісти також можуть описувати формати CSV, які розуміють інші програми, або визначати власні формати CSV спеціального призначення.

Об’єкти reader і writer модуля csv читають і записують послідовності. Програмісти також можуть читати та записувати дані у формі словника за допомогою класів DictReader і DictWriter.

Дивись також

PEP 305 - API файлів CSV

Пропозиція вдосконалення Python, яка пропонує це доповнення до Python.

Зміст модуля

Модуль csv визначає такі функції:

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

Return a reader object that will process lines from the given csvfile. A csvfile must be an iterable of strings, each in the reader’s defined csv format. A csvfile is most commonly a file-like object or list. If csvfile is a file object, it should be opened with newline=''. [1] An optional dialect parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the Dialect class or one of the strings returned by the list_dialects() function. The other optional fmtparams keyword arguments can be given to override individual formatting parameters in the current dialect. For full details about the dialect and formatting parameters, see section Діалекти та параметри форматування.

Кожен рядок, прочитаний із файлу csv, повертається як список рядків. Автоматичне перетворення типу даних не виконується, якщо не вказано параметр формату QUOTE_NONNUMERIC (у цьому випадку поля без лапок перетворюються на числа з плаваючою точкою).

Короткий приклад використання:

>>> import csv
>>> with open('eggs.csv', newline='') as csvfile:
...     spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
...     for row in spamreader:
...         print(', '.join(row))
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam
csv.writer(csvfile, dialect='excel', **fmtparams)

Return a writer object responsible for converting the user’s data into delimited strings on the given file-like object. csvfile can be any object with a write() method. If csvfile is a file object, it should be opened with newline='' [1]. An optional dialect parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the Dialect class or one of the strings returned by the list_dialects() function. The other optional fmtparams keyword arguments can be given to override individual formatting parameters in the current dialect. For full details about dialects and formatting parameters, see the Діалекти та параметри форматування section. To make it as easy as possible to interface with modules which implement the DB API, the value None is written as the empty string. While this isn’t a reversible transformation, it makes it easier to dump SQL NULL data values to CSV files without preprocessing the data returned from a cursor.fetch* call. All other non-string data are stringified with str() before being written.

Короткий приклад використання:

import csv
with open('eggs.csv', 'w', newline='') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=' ',
                            quotechar='|', quoting=csv.QUOTE_MINIMAL)
    spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
    spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
csv.register_dialect(name[, dialect[, **fmtparams]])

Пов’яжіть діалект з ім’ям. ім’я має бути рядком. Діалект можна вказати або шляхом передачі підкласу Dialect, або за допомогою аргументів ключового слова fmtparams, або обох, причому аргументи ключового слова замінюють параметри діалекту. Щоб отримати повну інформацію про діалекти та параметри форматування, перегляньте розділ Діалекти та параметри форматування.

csv.unregister_dialect(name)

Видаліть діалект, пов’язаний з name, із реєстру діалектів. Якщо name не є зареєстрованою назвою діалекту, виникає помилка Error.

csv.get_dialect(name)

Повертає діалект, пов’язаний з ім’ям. Якщо name не є зареєстрованою назвою діалекту, виникає помилка Error. Ця функція повертає незмінний Dialect.

csv.list_dialects()

Повернути назви всіх зареєстрованих діалектів.

csv.field_size_limit([new_limit])

Повертає поточний максимальний розмір поля, дозволений аналізатором. Якщо задано new_limit, це стає новим лімітом.

Модуль csv визначає такі класи:

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

Створіть об’єкт, який працює як звичайний читач, але зіставляє інформацію в кожному рядку з dict, ключі якого надаються необов’язковим параметром fieldnames.

The fieldnames parameter is a sequence. If fieldnames is omitted, the values in the first row of file f will be used as the fieldnames and will be omitted from the results. If fieldnames is provided, they will be used and the first row will be included in the results. Regardless of how the fieldnames are determined, the dictionary preserves their original ordering.

Якщо рядок містить більше полів, ніж назв полів, дані, що залишилися, поміщаються в список і зберігаються з іменем поля, визначеним restkey (за замовчуванням значення «Немає»). Якщо непорожній рядок містить менше полів, ніж імена полів, відсутні значення заповнюються значенням restval (яке за замовчуванням None).

Усі інші необов’язкові або ключові аргументи передаються базовому екземпляру reader.

If the argument passed to fieldnames is an iterator, it will be coerced to a list.

Змінено в версії 3.6: Повернені рядки тепер мають тип OrderedDict.

Змінено в версії 3.8: Повернені рядки тепер мають тип dict.

Короткий приклад використання:

>>> import csv
>>> with open('names.csv', newline='') as csvfile:
...     reader = csv.DictReader(csvfile)
...     for row in reader:
...         print(row['first_name'], row['last_name'])
...
Eric Idle
John Cleese

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

Create an object which operates like a regular writer but maps dictionaries onto output rows. The fieldnames parameter is a sequence of keys that identify the order in which values in the dictionary passed to the writerow() method are written to file f. The optional restval parameter specifies the value to be written if the dictionary is missing a key in fieldnames. If the dictionary passed to the writerow() method contains a key not found in fieldnames, the optional extrasaction parameter indicates what action to take. If it is set to 'raise', the default value, a ValueError is raised. If it is set to 'ignore', extra values in the dictionary are ignored. Any other optional or keyword arguments are passed to the underlying writer instance.

Зауважте, що на відміну від класу DictReader, параметр fieldnames класу DictWriter необов’язковий.

If the argument passed to fieldnames is an iterator, it will be coerced to a list.

Короткий приклад використання:

import csv

with open('names.csv', 'w', newline='') as csvfile:
    fieldnames = ['first_name', 'last_name']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
    writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})
    writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})
class csv.Dialect

Клас Dialect — це клас-контейнер, атрибути якого містять інформацію про те, як обробляти подвійні лапки, пробіли, розділювачі тощо. Через відсутність суворої специфікації CSV різні програми створюють дещо різні дані CSV. Екземпляри Dialect визначають, як поводитимуться екземпляри reader і writer.

Усі доступні назви Dialect повертаються list_dialects(), і їх можна зареєструвати в певних класах reader і writer через їх ініціалізатор (__init__) функціонує так:

import csv

with open('students.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile, dialect='unix')
class csv.excel

Клас excel визначає звичайні властивості файлу CSV, створеного Excel. Його зареєстровано з діалектною назвою 'excel.

class csv.excel_tab

Клас excel_tab визначає звичайні властивості створеного Excel файлу з роздільниками TAB. Його зареєстровано з діалектною назвою 'excel-tab.

class csv.unix_dialect

Клас unix_dialect визначає звичайні властивості файлу CSV, створеного в системах UNIX, тобто використання '\n' як символ закінчення рядка та взяття всіх полів у лапки. Він зареєстрований під діалектною назвою 'unix.

Added in version 3.2.

class csv.Sniffer

Клас Sniffer використовується для визначення формату файлу CSV.

Клас Sniffer надає два методи:

sniff(sample, delimiters=None)

Проаналізуйте поданий зразок і поверніть підклас Dialect, що відображає знайдені параметри. Якщо вказано необов’язковий параметр роздільники, він інтерпретується як рядок, що містить можливі дійсні символи роздільників.

has_header(sample)

Проаналізуйте зразок тексту (імовірно у форматі CSV) і поверніть True, якщо перший рядок виглядає як ряд заголовків стовпців. Перевіряючи кожен стовпець, буде розглянуто один із двох ключових критеріїв, щоб оцінити, чи містить вибірка заголовок:

  • з другого по n-й рядки містять числові значення

  • рядки з другого по n-й містять рядки, у яких довжина принаймні одного значення відрізняється від довжини передбачуваного заголовка цього стовпця.

Через двадцять рядів після першого ряду проводиться вибірка; якщо більше половини стовпців + рядків відповідають критеріям, повертається True.

Примітка

Цей метод є грубим евристичним і може давати як помилкові позитивні, так і негативні результати.

Приклад використання Sniffer:

with open('example.csv', newline='') as csvfile:
    dialect = csv.Sniffer().sniff(csvfile.read(1024))
    csvfile.seek(0)
    reader = csv.reader(csvfile, dialect)
    # ... process CSV file contents here ...

Модуль csv визначає такі константи:

csv.QUOTE_ALL

Вказує об’єктам writer взяти всі поля в лапки.

csv.QUOTE_MINIMAL

Вказує об’єктам writer брати в лапки лише ті поля, які містять спеціальні символи, такі як роздільник, quotechar або будь-які символи в lineterminator.

csv.QUOTE_NONNUMERIC

Вказує об’єктам writer взяти в лапки всі нечислові поля.

Instructs reader objects to convert all non-quoted fields to type float.

csv.QUOTE_NONE

Наказує об’єктам writer ніколи не брати поля в лапки. Коли поточний роздільник зустрічається у вихідних даних, йому передує поточний символ escapechar. Якщо escapechar не встановлено, запис викличе Error, якщо зустрінеться будь-який символ, який потребує екранування.

Instructs reader objects to perform no special processing of quote characters.

csv.QUOTE_NOTNULL

Instructs writer objects to quote all fields which are not None. This is similar to QUOTE_ALL, except that if a field value is None an empty (unquoted) string is written.

Instructs reader objects to interpret an empty (unquoted) field as None and to otherwise behave as QUOTE_ALL.

Added in version 3.12.

csv.QUOTE_STRINGS

Instructs writer objects to always place quotes around fields which are strings. This is similar to QUOTE_NONNUMERIC, except that if a field value is None an empty (unquoted) string is written.

Instructs reader objects to interpret an empty (unquoted) string as None and to otherwise behave as QUOTE_NONNUMERIC.

Added in version 3.12.

Примітка

Due to a bug, constants QUOTE_NOTNULL and QUOTE_STRINGS do not affect behaviour of reader objects. This bug is fixed in Python 3.13.

Модуль csv визначає такий виняток:

exception csv.Error

Викликається будь-якою з функцій у разі виявлення помилки.

Діалекти та параметри форматування

To make it easier to specify the format of input and output records, specific formatting parameters are grouped together into dialects. A dialect is a subclass of the Dialect class containing various attributes describing the format of the CSV file. When creating reader or writer objects, the programmer can specify a string or a subclass of the Dialect class as the dialect parameter. In addition to, or instead of, the dialect parameter, the programmer can also specify individual formatting parameters, which have the same names as the attributes defined below for the Dialect class.

Діалекти підтримують такі атрибути:

Dialect.delimiter

Односимвольний рядок, який використовується для розділення полів. За замовчуванням ',''.

Dialect.doublequote

Керує тим, як екземпляри quotechar, що з’являються всередині поля, повинні братися в лапки. Коли True, символ подвоюється. Коли False, escapechar використовується як префікс до quotechar. За замовчуванням True.

Під час виведення, якщо doublequote має значення False і escapechar не встановлено, виникає повідомлення Error, якщо quotechar знайдено в полі.

Dialect.escapechar

Односимвольний рядок, який використовується автором для екранування роздільника, якщо quoting встановлено як QUOTE_NONE, і quotechar, якщо doublequote має значення False. Під час читання escapechar видаляє будь-яке спеціальне значення наступного символу. За замовчуванням None, що вимикає екранування.

Змінено в версії 3.11: An empty escapechar is not allowed.

Dialect.lineterminator

Рядок, який використовується для завершення рядків, створених writer. За замовчуванням '\r\n'.

Примітка

reader жорстко розпізнає '\r' або '\n' як кінець рядка та ігнорує lineterminator. Така поведінка може змінитися в майбутньому.

Dialect.quotechar

Односимвольний рядок, який використовується для взяття в лапки полів, що містять спеціальні символи, такі як роздільник або quotechar, або які містять символи нового рядка. За замовчуванням '"'.

Змінено в версії 3.11: An empty quotechar is not allowed.

Dialect.quoting

Controls when quotes should be generated by the writer and recognised by the reader. It can take on any of the QUOTE_* constants and defaults to QUOTE_MINIMAL.

Dialect.skipinitialspace

When True, spaces immediately following the delimiter are ignored. The default is False.

Dialect.strict

Якщо True, викликати виняток Error на неправильному введенні CSV. Типовим значенням є False.

Об’єкти Reader

Об’єкти Reader (екземпляри DictReader та об’єкти, повернуті функцією reader()) мають такі публічні методи:

csvreader.__next__()

Повертає наступний рядок повторюваного об’єкта читача як список (якщо об’єкт повернуто з reader()) або dict (якщо це екземпляр DictReader), проаналізований відповідно до поточного Dialect. Зазвичай ви повинні називати це як next(reader).

Об’єкти Reader мають такі публічні атрибути:

csvreader.dialect

Доступний лише для читання опис діалекту, який використовує аналізатор.

csvreader.line_num

Кількість рядків, прочитаних із вихідного ітератора. Це не те саме, що кількість повернутих записів, оскільки записи можуть займати кілька рядків.

Об’єкти DictReader мають такий публічний атрибут:

DictReader.fieldnames

Якщо не передано як параметр під час створення об’єкта, цей атрибут ініціалізується під час першого доступу або коли перший запис зчитується з файлу.

Об’єкти Writer

writer objects (DictWriter instances and objects returned by the writer() function) have the following public methods. A row must be an iterable of strings or numbers for writer objects and a dictionary mapping fieldnames to strings or numbers (by passing them through str() first) for DictWriter objects. Note that complex numbers are written out surrounded by parens. This may cause some problems for other programs which read CSV files (assuming they support complex numbers at all).

csvwriter.writerow(row)

Запишіть параметр row в об’єкт файлу записувача, відформатований відповідно до поточного Dialect. Повертає значення, що повертається викликом методу write основного файлового об’єкта.

Змінено в версії 3.5: Додано підтримку довільних ітерацій.

csvwriter.writerows(rows)

Запишіть усі елементи в рядки (ітерація об’єктів рядок, як описано вище) до об’єкта файлу записувача, відформатованого відповідно до поточного діалекту.

Об’єкти Writer мають такий публічний атрибут:

csvwriter.dialect

Доступний лише для читання опис діалекту, який використовує автор.

Об’єкти DictWriter мають такий відкритий метод:

DictWriter.writeheader()

Запишіть рядок із іменами полів (як зазначено в конструкторі) до об’єкта файлу записувача, відформатованого відповідно до поточного діалекту. Повертає значення, що повертається внутрішнім викликом csvwriter.writerow().

Added in version 3.2.

Змінено в версії 3.8: writeheader() тепер також повертає значення, повернуте методом csvwriter.writerow(), який він використовує внутрішньо.

Приклади

Найпростіший приклад читання файлу CSV:

import csv
with open('some.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

Читання файлу в альтернативному форматі:

import csv
with open('passwd', newline='') as f:
    reader = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE)
    for row in reader:
        print(row)

Відповідний найпростіший можливий приклад написання:

import csv
with open('some.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerows(someiterable)

Since open() is used to open a CSV file for reading, the file will by default be decoded into unicode using the system default encoding (see locale.getencoding()). To decode a file using a different encoding, use the encoding argument of open:

import csv
with open('some.csv', newline='', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

Те саме стосується кодування, відмінного від стандартного системного кодування: укажіть аргумент кодування під час відкриття вихідного файлу.

Реєстрація нового діалекту:

import csv
csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)
with open('passwd', newline='') as f:
    reader = csv.reader(f, 'unixpwd')

Трохи розширеніше використання читача — виявлення та повідомлення про помилки:

import csv, sys
filename = 'some.csv'
with open(filename, newline='') as f:
    reader = csv.reader(f)
    try:
        for row in reader:
            print(row)
    except csv.Error as e:
        sys.exit('file {}, line {}: {}'.format(filename, reader.line_num, e))

І хоча модуль безпосередньо не підтримує розбір рядків, це легко зробити:

import csv
for row in csv.reader(['one,two,three']):
    print(row)

Виноски