# `csv` — CSV File Reading and Writing

소스 코드: Lib/csv.py

소위 CSV (Comma Separated Values – 쉼표로 구분된 값) 형식은 스프레드시트와 데이터베이스에 대한 가장 일반적인 가져오기 및 내보내기 형식입니다. CSV 형식은 RFC 4180에서 표준화된 방식으로 형식을 기술하기 전에 여러 해 동안 사용되었습니다. 잘 정의된 표준이 없다는 것은 다른 애플리케이션에 의해 생성되고 소비되는 데이터에 미묘한 차이가 존재한다는 것을 의미합니다. 이러한 차이로 인해 여러 소스의 CSV 파일을 처리하는 것이 번거로울 수 있습니다. 그러나 분리 문자와 인용 문자가 다양하기는 해도, 전체 형식은 유사하여 프로그래머에게 데이터 읽기와 쓰기 세부 사항을 숨기면서도 이러한 데이터를 효율적으로 조작할 수 있는 단일 모듈을 작성하는 것이 가능합니다.

`csv` 모듈은 CSV 형식의 표 형식 데이터를 읽고 쓰는 클래스를 구현합니다. 이 모듈은 프로그래머가 Excel에서 사용하는 CSV 형식에 대한 자세한 내용을 알지 못해도, “Excel에서 선호하는 형식으로 이 데이터를 쓰세요”나 “Excel에서 생성된 이 파일의 데이터를 읽으세요”라고 말할 수 있도록 합니다. 프로그래머는 다른 응용 프로그램에서 이해할 수 있는 CSV 형식을 기술하거나 자신만의 특수 용도 CSV 형식을 정의할 수 있습니다.

`csv` 모듈의 `reader`와 `writer` 객체는 시퀀스를 읽고 씁니다. 프로그래머는 `DictReader`와 `DictWriter` 클래스를 사용하여 딕셔너리 형식으로 데이터를 읽고 쓸 수 있습니다.

더 보기

PEP 305 - CSV File API

  파이썬에 이 모듈의 추가를 제안한 파이썬 개선 제안.

## 모듈 내용

`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 파일에서 읽은 각 행(row)은 문자열 리스트로 반환됩니다. `QUOTE_NONNUMERIC` 포맷 옵션을 지정하지 않으면 아무런 자동 데이터형 변환도 수행되지 않습니다 (지정하면 인용되지 않은 필드는 float로 변환됩니다).

  간단한 사용 예:

      >>> 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]])

  Associate dialect with name. name must be a string. The dialect can be specified either by passing a sub-class of `Dialect`, or by fmtparams keyword arguments, or both, with keyword arguments overriding parameters of the dialect. For full details about dialects and formatting parameters, see section 방언과 포매팅 파라미터.

csv.unregister_dialect(name)

  방언(dialect) 등록소에서 name과 관련된 연관된 방언을 삭제합니다. name이 등록된 방언 이름이 아니면 `Error`가 발생합니다.

csv.get_dialect(name)

  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)

  일반 판독기처럼 작동하지만 각 행(row)의 정보를 키가 선택적 fieldnames 매개 변수로 지정된 `dict`로 매핑하는 객체를 만듭니다.

  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.

  행에 fieldnames보다 많은 필드가 있으면, 나머지 데이터가 리스트에 저장되고 restkey(기본값은 `None`)로 지정된 필드 이름으로 저장됩니다. 비어 있지 않은 행에 fieldnames보다 필드 수가 적다면, 빠진 값은 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` 클래스와 달리 `DictWriter` 클래스의 fieldnames 매개 변수는 선택 사항이 아닙니다.

  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

  The `Dialect` class is a container class whose attributes contain information for how to handle doublequotes, whitespace, delimiters, etc. Due to the lack of a strict CSV specification, different applications produce subtly different CSV data. `Dialect` instances define how `reader` and `writer` instances behave.

  All available `Dialect` names are returned by `list_dialects()`, and they can be registered with specific `reader` and `writer` classes through their initializer (`__init__`) functions like this:

      import csv

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

class csv.excel

  `excel` 클래스는 Excel에서 생성한 CSV 파일의 일반적인 속성을 정의합니다. 방언 이름 `'excel'`로 등록됩니다.

class csv.excel_tab

  `excel_tab` 클래스는 Excel에서 생성된 TAB 구분 파일의 일반적인 속성을 정의합니다. 방언 이름 `'excel-tab'`으로 등록됩니다.

class csv.unix_dialect

  `unix_dialect` 클래스는 유닉스 시스템에서 생성된 CSV 파일의 일반적인 속성을 정의합니다. 즉, `'\n'`을 줄 종결자로 사용하고 모든 필드를 인용 처리합니다. 방언 이름 `'unix'`로 등록됩니다.

  Added in version 3.2.

class csv.Sniffer

  `Sniffer` 클래스는 CSV 파일의 형식을 추론하는 데 사용됩니다.

  `Sniffer` 클래스는 두 가지 메서드를 제공합니다:

  sniff(sample, delimiters=None)

    지정된 sample을 분석하고 발견된 파라미터를 반영하는 `Dialect` 서브 클래스를 반환합니다. 선택적인 delimiters 매개 변수를 주면, 가능한 유효한 구분 문자를 포함하는 문자열로 해석됩니다.

  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. Inspecting each column, one of two key criteria will be considered to estimate if the sample contains a header:

    - the second through n-th rows contain numeric values

    - the second through n-th rows contain strings where at least one value’s length differs from that of the putative header of that column.

    Twenty rows after the first row are sampled; if more than half of columns + rows meet the criteria, `True` is returned.

  참고

  This method is a rough heuristic and may produce both false positives and negatives.

`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` 객체에 delimiter, quotechar 또는 lineterminator에 들어있는 모든 문자와 같은 특수 문자를 포함하는 필드만 인용 처리하도록 지시합니다.

csv.QUOTE_NONNUMERIC

  `writer` 객체에 모든 숫자가 아닌 필드를 인용 처리하도록 지시합니다.

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

csv.QUOTE_NONE

  `writer` 객체에 필드를 절대 인용 처리하지 않도록 지시합니다. 출력 데이터에 현재 delimiter가 등장하면, 현재 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가 설정되지 않았으면, 필드에 quotechar가 있으면 `Error`가 발생합니다.

Dialect.escapechar

  quoting이 `QUOTE_NONE`으로 설정되었을 때 delimiter를, doublequote가 `False`일 때 quotechar를 이스케이프 하는데 기록기가 사용하는 한 문자로 된 문자열. 판독 시에, escapechar는 뒤따르는 문자에서 특별한 의미를 제거합니다. 기본값은 `None`이며, 이스케이핑을 비활성화합니다.

  버전 3.11에서 변경: An empty escapechar is not allowed.

Dialect.lineterminator

  `writer`에 의해 생성된 행을 종료하는 데 사용되는 문자열. 기본값은 `'\r\n'`입니다.

  참고

  `reader`는 `'\r'`이나 `'\n'`을 줄 종료로 인식하도록 하드 코딩되어 있으며, lineterminator를 무시합니다. 이 동작은 앞으로 변경될 수 있습니다.

Dialect.quotechar

  delimiter나 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`일 때, 잘못된 CSV 입력에서 예외 `Error`를 발생시킵니다. 기본값은 `False`입니다.

## 판독기 객체

판독기 객체(`DictReader` 인스턴스와 `reader()` 함수에서 반환한 객체)에는 다음과 같은 공용 메서드가 있습니다:

csvreader.__next__()

  Return the next row of the reader’s iterable object as a list (if the object was returned from `reader()`) or a dict (if it is a `DictReader` instance), parsed according to the current `Dialect`. Usually you should call this as `next(reader)`.

판독기 객체에는 다음과 같은 공용 어트리뷰트가 있습니다:

csvreader.dialect

  구문 분석기가 사용 중인 방언의 읽기 전용 설명.

csvreader.line_num

  소스 이터레이터에서 읽은 줄 수. 레코드가 여러 줄에 걸쳐 있을 수 있으므로, 이것은 반환된 레코드 수와 같지 않습니다.

DictReader 객체에는 다음과 같은 공용 어트리뷰트가 있습니다:

DictReader.fieldnames

  객체를 만들 때 매개 변수로 전달되지 않았으면, 이 어트리뷰트는 첫 번째 액세스 시나 파일에서 첫 번째 레코드를 읽을 때 초기화됩니다.

## 기록기 객체

`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)

  Write the row parameter to the writer’s file object, formatted according to the current `Dialect`. Return the return value of the call to the write method of the underlying file object.

  버전 3.5에서 변경: 임의의 이터러블 지원 추가.

csvwriter.writerows(rows)

  rows(위에서 설명한 row 객체의 이터러블)에 있는 모든 요소를 현재 방언에 따라 포매팅해서, 기록기의 파일 객체에 씁니다.

기록기 객체에는 다음과 같은 공용 어트리뷰트가 있습니다:

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)

시스템 기본 인코딩 이외의 다른 것으로 쓸 때도 마찬가지입니다: 출력 파일을 열 때 encoding 인자를 지정하십시오.

새로운 방언 등록하기:

    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`이 추가됩니다. csv 모듈은 자체 (유니버설) 줄 넘김 처리를 하므로, `newline=''`을 지정하는 것은 항상 안전합니다.