파일 입출력(File I/O) 기본

1. 서론: 프로그램의 결과물을 영구적으로 저장하기

이전 챕터에서 우리는 파이썬에서 텍스트 파일을 읽어와 프로그램 내에서 활용하는 방법을 배웠습니다. 이제 프로그램이 생성하거나 처리한 데이터를 외부 파일에 영구적으로 저장하는 방법을 알아볼 차례입니다. 프로그램이 실행될 때마다 생성되는 데이터는 휘발성이므로, 이를 파일에 저장하지 않으면 프로그램이 종료되는 순간 사라져 버립니다. 예를 들어, 사용자로부터 입력받은 정보를 저장하거나, 계산 결과를 기록하거나, 로그를 남기는 등의 작업은 모두 파일 쓰기 기능을 통해 이루어집니다. 이 챕터에서는 파이썬에서 텍스트 파일을 생성하고 내용을 쓰는 기본적인 방법과, 기존 파일에 내용을 추가하는 방법, 그리고 파일 쓰기 과정에서 발생할 수 있는 주의사항에 대해 깊이 있게 알아보겠습니다. 파일을 읽고 쓰는 능력은 여러분의 파이썬 프로그램이 외부 데이터와 상호작용하고, 실제 세계의 문제를 해결하는 데 필수적인 단계가 될 것입니다.

2. 파일 쓰기의 기본 단계

파이썬에서 파일을 쓰는 과정은 파일을 읽는 과정과 유사하게 세 단계로 나눌 수 있습니다.

  1. 파일 열기 (Open): open() 함수를 사용하여 파일을 엽니다. 이때 파일의 경로와 쓰기 모드('w', 'a', 'x')를 지정합니다.
  2. 파일 쓰기 (Write): 열린 파일 객체를 사용하여 파일에 내용을 기록합니다.
  3. 파일 닫기 (Close): 파일 작업을 마친 후에는 반드시 파일을 닫아줍니다. 이는 시스템 자원을 해제하고 데이터 손상을 방지하는 데 중요합니다.

2.1. open() 함수: 파일 열기 (쓰기 모드)

open() 함수는 파일을 열고 파일 객체(File Object)를 반환합니다. 쓰기 모드를 지정하는 것이 중요합니다.

file_object = open("파일경로", "모드")

주요 쓰기 모드:

  • 'w' (write): 쓰기 모드. 파일을 쓰기 위해 엽니다.
    • 파일이 이미 존재하면 내용을 모두 지우고 새로 작성합니다. (기존 내용 삭제)
    • 파일이 없으면 새로 생성합니다.
  • 'a' (append): 추가 모드. 파일을 쓰기 위해 엽니다.
    • 파일이 이미 존재하면 파일의 끝에 내용을 추가합니다. (기존 내용 유지)
    • 파일이 없으면 새로 생성합니다.
  • 'x' (exclusive creation): 독점 생성 모드. 파일을 새로 생성하고 쓰기 위해 엽니다.
    • 파일이 이미 존재하면 FileExistsError를 발생시킵니다. (덮어쓰기 방지)

텍스트 파일을 쓸 때는 주로 'w' 또는 'a' 모드를 사용합니다.

3. 텍스트 파일 쓰기 방법

파일 객체를 사용하여 파일에 내용을 쓰는 다양한 방법이 있습니다.

3.1. write(): 문자열 쓰기

write() 메서드는 파일에 문자열을 기록합니다. write() 메서드는 기록된 문자의 개수를 반환합니다. 줄 바꿈을 원하면 문자열 끝에 \n을 명시적으로 추가해야 합니다.

# 'w' 모드: 파일 생성 및 내용 덮어쓰기
with open("my_output.txt", "w") as f:
    f.write("Hello, Python File Writing!\n")
    f.write("This is the second line.\n")
    f.write("And this is the third.")

print("my_output.txt 파일이 생성되었습니다.")

# my_output.txt 파일 내용:
# Hello, Python File Writing!
# This is the second line.
# And this is the third.

3.2. writelines(): 리스트의 문자열 쓰기

writelines() 메서드는 문자열 리스트(또는 다른 반복 가능한 문자열 객체)의 모든 요소를 파일에 기록합니다. 각 요소가 한 줄로 기록되기를 원한다면, 각 문자열 끝에 \n을 포함해야 합니다.

lines_to_write = [
    "First line of text.\n",
    "Second line of text.\n",
    "Third line of text.\n"
]

with open("my_lines.txt", "w") as f:
    f.writelines(lines_to_write)

print("my_lines.txt 파일이 생성되었습니다.")

# my_lines.txt 파일 내용:
# First line of text.
# Second line of text.
# Third line of text.

4. 기존 파일에 내용 추가하기 ('a' 모드)

기존 파일의 내용을 유지하면서 새로운 내용을 파일의 끝에 추가하고 싶을 때는 'a' (append) 모드를 사용합니다.

# 먼저 my_log.txt 파일을 'w' 모드로 생성합니다.
with open("my_log.txt", "w") as f:
    f.write("로그 시작: 프로그램 실행됨\n")

print("my_log.txt 초기 내용 작성 완료.")

# 이제 'a' 모드로 내용을 추가합니다.
with open("my_log.txt", "a") as f:
    f.write("로그 추가: 사용자 로그인\n")
    f.write("로그 추가: 데이터 처리 완료\n")

print("my_log.txt에 내용이 추가되었습니다.")

# my_log.txt 파일 내용:
# 로그 시작: 프로그램 실행됨
# 로그 추가: 사용자 로그인
# 로그 추가: 데이터 처리 완료

5. 파일 쓰기 시 주의사항

5.1. 'w' 모드의 위험성: 기존 내용 덮어쓰기

'w' 모드는 파일이 이미 존재하면 기존 내용을 모두 삭제하고 새로 작성합니다. 중요한 데이터가 있는 파일을 실수로 'w' 모드로 열면 데이터가 영구적으로 손실될 수 있으므로 매우 주의해야 합니다.

# 경고: 이 코드를 실행하면 existing_data.txt의 모든 내용이 삭제됩니다!
# with open("existing_data.txt", "w") as f:
#     f.write("새로운 내용으로 덮어쓰기!")

5.2. FileExistsError 방지: 'x' 모드

파일이 이미 존재할 때 덮어쓰는 것을 방지하고 싶다면 'x' (exclusive creation) 모드를 사용합니다. 이 모드는 파일이 없으면 생성하고, 있으면 FileExistsError를 발생시킵니다.

try:
    with open("new_file_only.txt", "x") as f:
        f.write("이 파일은 한 번만 생성됩니다.\n")
    print("new_file_only.txt 파일이 성공적으로 생성되었습니다.")
except FileExistsError:
    print("new_file_only.txt 파일이 이미 존재합니다. 덮어쓰지 않습니다.")

# 첫 번째 실행 시: new_file_only.txt 파일이 성공적으로 생성되었습니다.
# 두 번째 실행 시: new_file_only.txt 파일이 이미 존재합니다. 덮어쓰지 않습니다.

5.3. 인코딩(Encoding) 지정

텍스트 파일을 읽거나 쓸 때, 문자 인코딩을 명시적으로 지정하는 것이 좋습니다. 특히 한글과 같은 비영어 문자를 다룰 때는 인코딩 문제가 발생할 수 있습니다. encoding 인자를 사용하여 인코딩 방식을 지정합니다. utf-8은 가장 널리 사용되는 유니코드 인코딩 방식입니다.

# 한글이 포함된 파일 쓰기
with open("korean_text.txt", "w", encoding="utf-8") as f:
    f.write("안녕하세요, 파이썬 파일 쓰기입니다.\n")
    f.write("한글 테스트입니다.")

print("korean_text.txt 파일에 한글 내용이 작성되었습니다.")

# 읽을 때도 동일한 인코딩 사용
with open("korean_text.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print("--- korean_text.txt 내용 ---")
    print(content)

인코딩을 지정하지 않으면 운영체제의 기본 인코딩이 사용되는데, 이는 시스템마다 다를 수 있어 호환성 문제가 발생할 수 있습니다.

6. with 문을 이용한 파일 처리 (가장 안전하고 권장)

파일 읽기 챕터에서 강조했듯이, 파일을 열고 닫는 과정을 매번 수동으로 관리하는 것은 번거롭고, close()를 호출하는 것을 잊어버릴 위험이 있습니다. with 문은 파일 작업을 마친 후 파일을 자동으로 닫아주므로, 파일 쓰기에서도 가장 권장되는 방법입니다.

# with 문을 사용하여 파일에 안전하게 쓰기
with open("safe_write.txt", "w", encoding="utf-8") as f:
    f.write("이 내용은 안전하게 파일에 기록됩니다.\n")
    f.write("with 문은 파일을 자동으로 닫아줍니다.")

print("safe_write.txt 파일에 내용이 안전하게 작성되었습니다.")

7. 결론: 프로그램의 영속성을 위한 파일 쓰기

이 챕터를 통해 여러분은 파이썬에서 텍스트 파일을 생성하고 내용을 쓰는 기본적인 방법과, 기존 파일에 내용을 추가하는 방법, 그리고 파일 쓰기 과정에서 발생할 수 있는 주의사항에 대해 깊이 있게 학습했습니다. open() 함수의 다양한 쓰기 모드('w', 'a', 'x')의 차이점을 이해하고, write()writelines() 메서드를 사용하여 파일에 데이터를 기록하는 방법을 배웠습니다. 또한, 인코딩의 중요성과 with 문을 이용한 안전한 파일 처리 방법까지 살펴보았습니다.

파일 쓰기는 프로그램이 생성하거나 처리한 데이터를 영구적으로 저장하는 데 필수적인 기능입니다. 로그 기록, 데이터 내보내기, 설정 파일 저장 등 실제 프로그래밍에서 파일 쓰기는 빈번하게 사용됩니다. 특히 'w' 모드의 위험성을 인지하고 with 문을 사용하는 습관을 들이는 것은 코드의 안정성과 신뢰성을 높이는 데 매우 중요합니다.

이제 여러분은 파이썬 프로그램이 외부 파일에서 데이터를 읽고 쓸 수 있는 능력을 갖추게 되었습니다. 다음 챕터에서는 with 문을 더 깊이 있게 다루며, 파일 처리뿐만 아니라 다른 자원 관리에도 with 문이 어떻게 활용될 수 있는지 알아보겠습니다. 오늘 배운 파일 쓰기 방법을 활용하여 다양한 데이터를 파일에 직접 기록해 보면서, 여러분의 파이썬 실력을 더욱 단단하게 다지세요!

파일 입출력(File I/O) 기본