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 which will iterate over lines in the given csvfile. csvfile can be any object which supports the iterator protocol and returns a string each time its __next__() method is called — file objects and list objects are both suitable. 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. Regardless of how the fieldnames are determined, the dictionary preserves their original ordering.

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

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

Змінено в версії 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 необов’язковий.

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

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.

Нове в версії 3.2.

class csv.Sniffer

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

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

sniff(sample, delimiters=None)

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

has_header(sample)

Analyze the sample text (presumed to be in CSV format) and return True if the first row appears to be a series of column headers.

Приклад використання 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 the reader to convert all non-quoted fields to type float.

csv.QUOTE_NONE

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

Instructs reader to perform no special processing of quote characters.

Модуль 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 having a set of specific methods and a single validate() method. 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, що вимикає екранування.

Dialect.lineterminator

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

Примітка

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

Dialect.quotechar

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

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 (see section Зміст модуля) and defaults to QUOTE_MINIMAL.

Dialect.skipinitialspace

When True, whitespace immediately following the delimiter is 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 мають такий публічний атрибут:

csvreader.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().

Нове в версії 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.getpreferredencoding()). 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)

Виноски

1(1,2)

Якщо newline='' не вказано, нові рядки, вбудовані в поля в лапках, не будуть інтерпретовані належним чином, а на платформах, які використовують \r\n розрядки під час запису, буде додатковий \r додано. Завжди має бути безпечно вказувати newline='', оскільки модуль csv виконує власну (universal) обробку нового рядка.