csv — CSV 파일 읽고 쓰기
csv — CSV 파일 읽고 쓰기
소위 CSV(콤마로 구분된 값, Comma Separated Values) 형식은 스프레드시트와 데이터베이스에서 가장 흔한 import/export 형식입니다. CSV 형식은 RFC 4180에서 표준화하려는 시도 이전부터 수년간 사용되어 왔습니다. 잘 정의된 표준이 없다는 것은 서로 다른 애플리케이션이 생산하고 소비하는 데이터에 미묘한 차이가 자주 존재한다는 뜻입니다. 이런 차이 때문에 여러 출처의 CSV 파일을 처리하기가 번거로울 수 있지만, 구분자와 인용 문자는 다양해도 전반적인 형식은 충분히 비슷해서 하나의 모듈로 그러한 데이터를 효율적으로 다룰 수 있습니다.
본문
csv 모듈은 CSV 형식의 표 형식 데이터를 읽고 쓰는 클래스들을 구현합니다. 프로그래머는 Excel이 선호하는 형식으로 데이터를 쓰거나 Excel이 만든 파일의 데이터를 읽을 수 있습니다. 다른 애플리케이션이 이해하는 CSV 형식을 설명하거나 자신만의 특수한 CSV 형식을 정의할 수도 있습니다.
csv 모듈의 reader와 writer 객체는 시퀀스를 읽고 쓰며, DictReader와 DictWriter 클래스로 딕셔너리 형태의 데이터를 읽고 쓸 수도 있습니다. 참고로 PEP 305가 이 기능을 제안했습니다.
함수
csv.reader(csvfile, /, dialect='excel', **fmtparams)— 주어진csvfile의 줄을 처리할 reader 객체를 반환합니다. csvfile은 reader의 정의된 CSV 형식의 문자열을 각각 담은 이터러블이어야 하며, 대부분 파일류 객체나 리스트입니다. 파일 객체라면newline=''으로 열어야 합니다. 각 행은 문자열의 리스트로 반환됩니다.QUOTE_NONNUMERIC형식 옵션이 지정되지 않으면 자동 형변환은 없습니다.csv.writer(csvfile, /, dialect='excel', **fmtparams)— 사용자 데이터를 구분된 문자열로 변환하는 writer 객체를 반환합니다.None값은 빈 문자열로 쓰여집니다. 다른 모든 비문자열 데이터는 쓰기 전에str()로 문자열화됩니다.csv.register_dialect(name, /, dialect='excel', **fmtparams)—name과 dialect를 연결합니다.csv.unregister_dialect(name)— dialect 레지스트리에서name과 연결된 dialect를 삭제합니다. 등록된 이름이 아니면Error를 발생시킵니다.csv.get_dialect(name)—name과 연결된 dialect를 반환합니다. 등록된 이름이 아니면Error를 발생시킵니다.csv.list_dialects()— 등록된 모든 dialect의 이름을 반환합니다.csv.field_size_limit([new_limit])— 파서가 허용하는 현재 최대 필드 크기를 반환합니다.new_limit가 주어지면 그 값이 새 제한이 됩니다.
클래스
csv.DictReader(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)는 일반 reader처럼 동작하되 각 행의 정보를 선택적 fieldnames 매개변수로 키가 주어진 dict에 매핑하는 객체를 만듭니다. fieldnames를 생략하면 파일 f의 첫 행 값이 필드 이름으로 사용되고 결과에서 제외됩니다. 행에 필드 이름보다 많은 필드가 있으면 나머지 데이터는 restkey(기본값 None)가 지정한 필드 이름으로 리스트에 저장되고, 필드보다 적으면 빠진 값이 restval(기본값 None)로 채워집니다. 3.6부터 반환 행은 OrderedDict, 3.8부터는 dict 타입입니다.
csv.Dialect와 여러 상수(QUOTE_ALL, QUOTE_MINIMAL, QUOTE_NONNUMERIC, QUOTE_NONE) 등이 형식 매개변수로 제공됩니다. dialect와 형식 매개변수에 대한 자세한 내용은 Dialects and Formatting Parameters 절을 참고하세요.
예제
파일을 시스템 기본 인코딩이 아닌 다른 인코딩으로 디코드하려면 open의 encoding 인자를 사용합니다:
import csv
with open('some.csv', newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
새 dialect를 등록하고 항목별로 오류를 잡아 보고하는 좀 더 고급 사용 예는 다음과 같습니다:
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(f'file {filename}, line {reader.line_num}: {e}')