C.W.K.
Stream
Lesson 01 of 06 · published

open() — 모드 / 인코딩 / file 객체

~20 min · open, file, mode, encoding

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

open() — 일꾼

open(path, mode='r', encoding=None) 가 읽거나 쓸 file 객체 반환. 가장 중요한 두 인자 — 모드와 인코딩. 모드는 읽기/쓰기 그리고 텍스트/바이너리 알려줘. 인코딩은 바이트와 텍스트 변환 — UTF-8 이 현대 디폴트, 다른 거 거의 안 필요해.

모드 문자 — 결합되는 5 글자

r 읽기 (디폴트), w 쓰기 (먼저 truncate), a 추가, x 생성-only (있으면 실패), + 읽기+쓰기, b 바이너리, t 텍스트 (디폴트). 조합 — rb 바이너리 읽기, w+ 쓰기+읽기, a+b 추가+읽기+바이너리. 텍스트/바이너리 차이 중요 — 텍스트 모드가 인코딩/디코딩 + 줄바꿈 변환, 바이너리 모드는 raw 바이트.

항상 with 문

with open(path) as f: 가 블록 안에서 예외 raise 되어도 파일 닫힘 보장. 대안 — f = open(path); ... f.close() — 는 open 과 close 사이 예외 안 날 때만 맞음. 약속할 수 없는 제약. with 써. 끝.

encoding 인자 — UTF-8 디폴트가 사실 X

놀라움 — open() 이 지정 안 할 때 시스템 디폴트 인코딩 사용, Windows 에선 종종 cp1252 같은 거. 크로스플랫폼 코드 물려. 해결 — open(path, encoding='utf-8'), 텍스트 읽기/쓰기 항상. Python 3.11+ 가 encoding="locale" 추가해서 locale 기반 동작 명시적.

주의: 같은 파일에 텍스트와 바이너리 모드 시간 다르게 섞으면 버그 레시피. 하나 골라 박아. 둘 다 필요하면 두 파일 객체 또는 명시적 seek-and-reopen. r+b 로 전환하지 마.

Code

open() — 텍스트 읽기/쓰기·python
# 파일 통째 읽기
with open("/etc/hostname", encoding="utf-8") as f:
    content = f.read()
print(content.strip())

# 쓰기 — overwrite
with open("/tmp/out.txt", "w", encoding="utf-8") as f:
    f.write("hello\n")
    f.write("world\n")

# Append
with open("/tmp/out.txt", "a", encoding="utf-8") as f:
    f.write("more\n")

# 생성-only — 있으면 실패
try:
    with open("/tmp/out.txt", "x", encoding="utf-8") as f:
        f.write("여기까지 안 옴")
except FileExistsError as e:
    print("이미 존재:", e)
줄 단위 읽기 — streaming idiom·python
# 큰 파일에 이거 X
# data = open("big.log", encoding="utf-8").read()      # 전부 로드

# 이거 — file 객체가 줄 단위로 iterable
with open("/tmp/out.txt", encoding="utf-8") as f:
    for line in f:
        print("got:", line.rstrip("\n"))

# .readlines() — 줄 list, eager
with open("/tmp/out.txt", encoding="utf-8") as f:
    lines = f.readlines()
    print(lines)              # ['hello\n', 'world\n', 'more\n']
바이너리 모드 — 바이트 in/out·python
# 바이너리 파일 읽기
with open("/bin/ls", "rb") as f:
    header = f.read(4)
print(header)                  # b'\x7fELF' on Linux/macOS

# 바이트 쓰기
with open("/tmp/raw.bin", "wb") as f:
    f.write(b"\xDE\xAD\xBE\xEF")

# 텍스트와 바이너리는 다른 파일 모드
try:
    with open("/tmp/raw.bin", "r") as f:    # 텍스트 모드!
        f.read()                              # UnicodeDecodeError 가능
except UnicodeDecodeError as e:
    print("예상대로:", e)
Seek + tell — 위치 변경·python
# 파일 안 seek 하려면 read+write 로 열기
with open("/tmp/seek.txt", "w+", encoding="utf-8") as f:
    f.write("hello world")
    print("위치:", f.tell())          # 11
    f.seek(0)
    print(f.read(5))                      # 'hello'
    f.seek(6)
    print(f.read())                       # 'world'

# 멀티바이트 컨텐츠에 정확한 byte seeking 은 바이너리 모드 필요
텍스트 파일 항상 인코딩 지정·python
# Linux 에선 작동, Windows 시스템 locale 이 UTF-8 안 만들면 깨질 수 있음
# with open("data.txt") as f:
#     contents = f.read()

# 항상 인코딩 지정
with open("/tmp/out.txt", encoding="utf-8") as f:
    contents = f.read()
print(contents[:50])

# 3.11+ 가 명시적 'locale 사용' 위해 "locale" 추가 — 디폴트와 다름
# with open("data.txt", encoding="locale") as f: ...

External links

Exercise

세 프로그램 — (a) 파일 /tmp/quest_test.txt 생성, 세 줄 쓰기 (open + with). (b) 같은 파일 읽기로 열고 각 줄을 줄 번호와 함께 출력. (c) 네 번째 줄 추가, 다시 읽어서 네 줄 다 있는지 확인. 항상 encoding='utf-8' 지정. with 블록 사용.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.