2.27. 읽기와 쓰기¶
파일은 디스크에 존재합니다. Python은 open() 을 통해 파일에 접근하며, 이는 파일 객체 를 반환하고 그 메서드들이 기저의 바이트를 읽고 씁니다.
2.27.1. open과 모드¶
첫 번째 인수는 경로이고, 두 번째는 모드 입니다 – 파일을 어떻게 사용할지를 Python에 알려주는 짧은 문자열입니다:
"r"– 읽기(기본값). 기존 파일을 읽기 위해 엽니다."w"– 쓰기. 새 파일을 만들거나 기존 파일을 비어 있도록 잘라냅니다(truncate)."a"– 추가. 잘라내지 않고 파일의 끝에서 쓰기 위해 엽니다.위의 어느 것에든 붙인
"b"("rb","wb","ab") – 바이너리 모드. 파일의 내용이str이 아니라bytes입니다.
f = open("notes.txt", "r")
text = f.read()
f.close()
2.27.2. 컨텍스트 관리자를 사용하기¶
위 패턴은 open() 과 close 사이의 무언가가 예외를 발생시키면 파일 핸들을 누수시킵니다. 해결책은 with 문입니다(컨텍스트 관리자 참조):
with open("notes.txt") as f:
text = f.read()
# f is closed here, even if read() failed
이것이 표준 형태입니다 – 매번 이렇게 작성하십시오.
2.27.3. 읽기¶
파일 객체는 여러 가지 읽기 방식을 지원합니다:
io.IOBase.read()– 파일 전체(또는 N바이트)를 읽어 단일 문자열(또는 바이트 객체)로 반환합니다.io.IOBase.readline()– 끝의"\n"을 포함하여 한 줄을 읽습니다.파일을 직접 순회하면 한 번에 한 줄씩 나오며, 파일 전체를 한꺼번에 읽는 것보다 메모리 사용량이 훨씬 적습니다.
with open("log.txt") as f:
for line in f:
print(line.rstrip())
str.rstrip() 은 출력하기 전에 끝의 개행을 제거하여 출력이 두 줄 간격으로 벌어지지 않게 합니다.
2.27.4. 쓰기¶
파일을 "w" 모드로 열고 io.IOBase.write() 를 사용합니다:
with open("out.txt", "w") as f:
f.write("hello\n")
f.write("world\n")
io.IOBase.write() 는 개행을 추가하지 않습니다 – 여러분이 준 바이트(텍스트 모드에서는 문자)를 정확히 그대로 씁니다.
2.27.5. 텍스트 대 바이너리¶
텍스트 모드(기본값, "b" 없는 "r" / "w")는 들어오는 바이트를 기본 인코딩을 사용해 str 로 디코딩하고, 나가는 str 을 다시 바이트로 인코딩합니다. 설정, 로그, JSON 등 텍스트인 모든 것에 사용하십시오.
바이너리 모드("rb" / "wb")는 디코딩 단계를 건너뛰고 bytes 를 반환합니다. 이미지, struct로 패킹된 레코드, 네트워크 캡처 등 모든 바이트가 중요하고 파일이 사람이 읽을 수 없는 모든 것에 사용하십시오.
2.27.6. 파일 목록 보기와 제거하기¶
os 모듈은 파일 객체 자체에는 없는 파일 시스템 연산을 노출합니다:
os.listdir()– 디렉터리 안의 이름 목록을 반환합니다.os.remove()– 파일을 삭제합니다.os.rename()– 파일 이름을 변경합니다.os.stat()– 파일 메타데이터(크기, 수정 시각, …).os.mkdir()– 새 디렉터리를 만듭니다.
import os
for name in os.listdir("/"):
print(name)
파일이나 디렉터리가 없을 수 있는 경우 이 연산들 주위에서 OSError 를 잡으십시오 – 이 연산은 실제 스크립트에서 예외가 자주 나타나는 곳 중 하나입니다.