파이썬 교육 챕터 46 파일 입출력 기본 읽기

파일 입출력(File I/O) 기본: 텍스트 파일 읽기

1. 서론: 프로그램과 외부 데이터의 소통

지금까지 우리는 파이썬 프로그램 내에서 데이터를 생성하고, 변수에 저장하며, 조작하는 방법을 배웠습니다. 하지만 프로그램이 다루는 데이터는 대부분 외부 파일에 저장되어 있습니다. 예를 들어, 설정 파일, 로그 파일, 텍스트 문서, CSV 파일 등 다양한 형태의 데이터가 파일 시스템에 존재합니다. 프로그램이 이러한 외부 데이터를 활용하려면 파일에서 데이터를 읽어와야 하고, 반대로 프로그램이 생성한 데이터를 영구적으로 저장하려면 파일에 데이터를 써야 합니다. 이처럼 프로그램이 파일 시스템과 데이터를 주고받는 과정을 ‘파일 입출력(File Input/Output, File I/O)’이라고 합니다. 이 챕터에서는 파일 입출력의 가장 기본적인 단계인 텍스트 파일을 읽는 방법에 대해 깊이 있게 알아보겠습니다. 파일을 읽는 능력은 여러분의 파이썬 프로그램이 외부 데이터와 상호작용하고, 실제 세계의 문제를 해결하는 데 필수적인 첫걸음이 될 것입니다.

2. 파일 읽기의 기본 단계

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

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

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

open() 함수는 파일을 열고 파일 객체(File Object)를 반환합니다. 이 파일 객체를 통해 파일의 내용을 읽거나 쓸 수 있습니다.

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

주요 모드:

  • 'r' (read): 읽기 모드. 파일을 읽기 위해 엽니다. (기본값)
  • 'w' (write): 쓰기 모드. 파일을 쓰기 위해 엽니다. 파일이 이미 존재하면 내용을 모두 지우고 새로 작성하며, 파일이 없으면 새로 생성합니다.
  • 'a' (append): 추가 모드. 파일을 쓰기 위해 엽니다. 파일이 이미 존재하면 파일의 끝에 내용을 추가하며, 파일이 없으면 새로 생성합니다.
  • 'x' (exclusive creation): 독점 생성 모드. 파일을 새로 생성하고 쓰기 위해 엽니다. 파일이 이미 존재하면 FileExistsError를 발생시킵니다.
  • 'b' (binary): 이진 모드. 바이너리 파일(이미지, 동영상 등)을 다룰 때 사용합니다. 'rb', 'wb'와 같이 다른 모드와 함께 사용됩니다.
  • 't' (text): 텍스트 모드. 텍스트 파일을 다룰 때 사용합니다. (기본값) 'rt', 'wt'와 같이 다른 모드와 함께 사용됩니다.

텍스트 파일을 읽을 때는 주로 'r' 모드를 사용합니다.

2.2. 파일 경로 지정

파일 경로는 절대 경로(Absolute Path) 또는 상대 경로(Relative Path)로 지정할 수 있습니다.

  • 절대 경로: 파일의 전체 경로를 처음부터 끝까지 명시합니다. (예: C:\Users\YourName\Documents\my_file.txt, /home/yourname/documents/my_file.txt)
  • 상대 경로: 현재 스크립트가 실행되는 디렉토리를 기준으로 파일의 위치를 명시합니다. (예: my_file.txt, data/my_file.txt)

윈도우에서는 경로 구분자로 백슬래시(\)를 사용하지만, 파이썬에서는 백슬래시가 이스케이프 문자로 해석될 수 있으므로, 슬래시(/)를 사용하거나 백슬래시를 두 번(\\) 사용하거나, 문자열 앞에 r을 붙여 Raw String으로 만드는 것이 좋습니다.

# 윈도우 경로 예시
file_path_win1 = "C:/Users/YourName/Documents/my_file.txt"
file_path_win2 = "C:\\Users\\YourName\\Documents\\my_file.txt"
file_path_win3 = r"C:\Users\YourName\Documents\my_file.txt"

# 리눅스/macOS 경로 예시
file_path_linux = "/home/yourname/documents/my_file.txt"

3. 텍스트 파일 읽기 방법

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

먼저, sample.txt라는 파일을 만들고 다음 내용을 저장해 주세요.

# sample.txt
Line 1: Hello Python
Line 2: File I/O is important
Line 3: This is the third line.
Line 4: End of file.

3.1. read(): 파일 전체 내용 읽기

read() 메서드는 파일의 전체 내용을 하나의 문자열로 읽어옵니다. 인자로 읽어올 문자(바이트) 수를 지정할 수도 있습니다.

# 파일 열기
f = open("sample.txt", "r")

# 파일 전체 내용 읽기
content = f.read()
print(content)

# 파일 닫기
f.close()

# 출력:
# Line 1: Hello Python
# Line 2: File I/O is important
# Line 3: This is the third line.
# Line 4: End of file.

3.2. readline(): 한 줄씩 읽기

readline() 메서드는 파일에서 한 줄씩 읽어옵니다. 더 이상 읽을 줄이 없으면 빈 문자열("")을 반환합니다.

f = open("sample.txt", "r")

line1 = f.readline()
print(line1, end='') # print()는 기본적으로 줄 바꿈을 추가하므로, end=''로 중복 방지

line2 = f.readline()
print(line2, end='')

f.close()

# 출력:
# Line 1: Hello Python
# Line 2: File I/O is important

3.3. readlines(): 모든 줄을 리스트로 읽기

readlines() 메서드는 파일의 모든 줄을 읽어와 각 줄을 요소로 하는 리스트를 반환합니다. 각 줄의 끝에는 줄 바꿈 문자(\n)가 포함됩니다.

f = open("sample.txt", "r")

lines = f.readlines()
print(lines)

f.close()

# 출력: ['Line 1: Hello Python\n', 'Line 2: File I/O is important\n', 'Line 3: This is the third line.\n', 'Line 4: End of file.\n']

# 각 줄을 깔끔하게 출력
for line in lines:
    print(line.strip()) # strip()으로 줄 바꿈 문자 제거

3.4. for 루프를 이용한 파일 읽기 (가장 권장)

파일 객체는 그 자체가 반복 가능한(iterable) 객체이므로, for 루프를 사용하여 파일의 내용을 한 줄씩 효율적으로 읽을 수 있습니다. 이 방법은 메모리 효율적이며, 코드가 간결하여 가장 권장됩니다.

f = open("sample.txt", "r")

for line in f:
    print(line.strip()) # 각 줄의 끝에 있는 줄 바꿈 문자 제거

f.close()

# 출력:
# Line 1: Hello Python
# Line 2: File I/O is important
# Line 3: This is the third line.
# Line 4: End of file.

4. 파일 닫기 (close())의 중요성

파일 작업을 마친 후에는 반드시 close() 메서드를 호출하여 파일을 닫아야 합니다. 파일을 닫지 않으면 다음과 같은 문제가 발생할 수 있습니다.

  • 자원 누수: 운영체제는 열린 파일에 대한 자원을 할당합니다. 파일을 닫지 않으면 이 자원이 계속 점유되어 시스템 성능에 영향을 줄 수 있습니다.
  • 데이터 손상/유실: 파일에 데이터를 쓰는 경우, close()를 호출해야 버퍼에 있는 데이터가 실제로 파일에 기록됩니다. 닫지 않으면 데이터가 유실될 수 있습니다.
  • 다른 프로그램의 접근 제한: 파일이 열려 있는 동안에는 다른 프로그램이 해당 파일에 접근하지 못할 수 있습니다.

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

파일을 열고 닫는 과정을 매번 수동으로 관리하는 것은 번거롭고, close()를 호출하는 것을 잊어버릴 위험이 있습니다. 파이썬은 이러한 문제를 해결하기 위해 with 문을 제공합니다. with 문을 사용하면 파일 작업을 마친 후 파일을 자동으로 닫아줍니다. 이는 예외가 발생하더라도 파일을 안전하게 닫아주므로 가장 권장되는 방법입니다.

with open("sample.txt", "r") as f:
    content = f.read()
    print(content)

# with 블록을 벗어나면 파일 f는 자동으로 닫힙니다.
# f.close()를 명시적으로 호출할 필요가 없습니다.

with 문은 파일 객체가 __enter____exit__ 메서드를 구현하는 ‘컨텍스트 관리자(Context Manager)’이기 때문에 가능합니다. with 블록에 진입할 때 __enter__가 호출되고, 블록을 벗어날 때 (정상 종료든 예외 발생이든) __exit__가 호출되어 파일을 자동으로 닫아줍니다.

6. 결론: 외부 데이터와의 효율적인 상호작용

이 챕터를 통해 여러분은 파이썬에서 텍스트 파일을 읽는 기본적인 방법과 그 과정에서 필요한 open(), read(), readline(), readlines() 메서드, 그리고 for 루프를 이용한 효율적인 파일 읽기 방법에 대해 깊이 있게 학습했습니다. 또한, 파일 닫기(close())의 중요성과 함께, 파일을 안전하고 편리하게 처리할 수 있는 with 문의 활용법까지 살펴보았습니다.

파일 입출력은 프로그램이 외부 데이터와 상호작용하는 데 필수적인 기능입니다. 설정 파일을 읽어오거나, 대량의 데이터를 처리하거나, 로그 파일을 분석하는 등 실제 프로그래밍에서 파일 읽기는 빈번하게 사용됩니다. 특히 with 문을 사용하는 습관을 들이는 것은 코드의 안정성과 가독성을 높이는 데 매우 중요합니다.

이제 여러분은 파이썬 프로그램이 외부 파일에서 데이터를 읽어올 수 있는 능력을 갖추게 되었습니다. 다음 챕터에서는 파일에 데이터를 쓰는 방법, 즉 텍스트 파일을 생성하고 내용을 추가하는 방법에 대해 자세히 알아보겠습니다. 파일을 읽고 쓰는 능력은 여러분의 파이썬 프로그램을 더욱 강력하고 유용하게 만들 것입니다. 오늘 배운 파일 읽기 방법을 활용하여 다양한 텍스트 파일을 직접 읽어 보면서, 여러분의 파이썬 실력을 더욱 단단하게 다지세요!

파이썬 교육 챕터 46 파일 입출력 기본 읽기