[학습 일기 #16] 파일 입출력 & 예외 처리

Ariel_Jeong·2026년 1월 7일

[학습 일기 시리즈]

목록 보기
16/44

오늘 다룰 주제는 지난 수업에서 배운 파일 입출력과 예외 처리에 관한 내용이다.

이때부터는 예습을 못한 내용이기 때문에
매일 과제를 해결하고 그 과정을 회고하는 내용 + 그날 배운 개념 정리를 담으려했으나

우선은 코드를 반복작성하며 몸에 익히는데에 집중하느라
뒤늦게 복습하는 느낌으로 작성하게 되었다.

그럼 먼저 파일 입출력에 대해 알아보자.


* 예시 코드의 출처는 오즈코딩스쿨이다


1. 파일 입출력🗂️

파일 입출력은 '프로그램'과 '외부 파일'간의 데이터 교환이 가능하게 해주고,
정보를 영구적으로 보존하고 공유할 수 있도록 해주는 기능이다.

예를 들어,
환자의 진료 기록이나 검사 결과같은 데이터들을 따로 파일로 저장할 수 있고 백업도 가능하다.


1.1. open()함수

open()함수의 기본 문법은 아래와 같다.

file = open('파일명을 포함한 파일이 존재하는 위치', '모드', encoding='utf-8')

이 때 주의해야할 점은
작업을 다 수행하고 나면 반드시 .close()를 사용해 닫아주어야 한다는 점이다.
닫지 않으면 메모리 누수가 발생하며 다른 프로그램에서 접근하지 못하는 문제가 발생할 수 있다.

파일 모드의 종류

  • 'r': 읽기 모드(기본값이며 기존 파일 내용을 읽기 위해 사용된다)
  • 'w': 쓰기 모드(새로운 내용으로 덮어쓰기 위함이며 기존 내용은 삭제된다)
  • 'a': 추가 모드(기존 내용 뒤에 새로운 내용을 추가하기 위해 사용된다)
  • 'r+': 읽기/쓰기 모드(파일을 읽고, 수정할 수 있다)

* encoding='utf-8'는 텍스트를 컴퓨터가 이해할 수 있는 바이트로 변환하기 위함이다.


1.2. with문

with 문을 사용하면 작업 후 파일을 자동으로 닫아주기 때문에 안전하게 파일을 처리할 수 있으며,
기본 문법은 아래와 같다.

with open('파일명을 포함한 파일이 존재하는 위치', '모드', encoding='utf-8') as file:
작업 내용

1.3. 파일을 읽는 다양한 방법

1.3.1. 전체 내용 읽기

medical_records.txt라는 파일이 현재 폴더에 있다고 가정해보자
전체 내용을 읽고 싶다면 아래와 같이 작성해줄 수 있다.

with open('medical_records.txt', 'r', encoding='utf-8') as file:
    content = file.read()               # 전체 파일 내용
    print(content)

### 1.3.2. 첫 번째 줄만 읽기 ```.readline()```메소드를 사용하면 첫 번째 줄만 읽을 수 있다.
with open('medical_records.txt', 'r', encoding='utf-8') as file:
    first_line = file.readline().strip()   # .strip()은 불필요한 공백 제거를 위함
    print(f"첫 번째 기록: {first_line}")

1.3.3. 모든 줄을 '리스트'로 읽기

.readlines()를 사용하면 모든 줄을 리스트로 읽을 수 있다.

with open('medical_records.txt', 'r', encoding='utf-8') as file:
    all_lines = file.readlines()            # 모든 줄을 리스트로 가져옴
    for i, line in enumerate(all_lines, 1): # 반복문을 돌며 (줄 번호: 내용) 출력
        print(f"{i}번째: {line.strip()}")

cf) 특정 줄(한 줄)만 읽고 싶다면?

n = 2    # 원하는 줄

# 방법 1
with open('medical_records.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()
    print(lines[n-1])    # 인덱스 번호라 -1 필요

print(f"{'='*30}\n")

# 방법 2
import linecache
line = linecache.getline('medical_records.txt', n)
print(line)

위의 두 방법 중 편한 것을 사용하면 된다.


1.3.3. 모든 줄을 'for문'으로 읽기

with open('medical_records.txt', 'r', encoding='utf-8') as file:
    for line_num, line in enumerate(file, 1):  # 파일을 한 줄씩 순회
        record = line.strip()               # 현재 줄의 진료기록
        print(f"환자 {line_num}: {record}")

1.4. 파일을 쓰는 다양한 방법

1.4.1. 새 파일 생성

with open('prescription.txt', 'w', encoding='utf-8') as file:
    prescription_data = "환자: 박환자\n의사: 김의사\n처방: 혈압약 1일 2회\n"  
    file.write(prescription_data)

모드를 'w'로 두고 file.write()를 하면 된다.


1.4.2. 기존 파일에 추가

with open('prescription.txt', 'a', encoding='utf-8') as file:
    additional_info = "\n복용기간: 30일\n주의사항: 식후 복용" 
    file.write(additional_info)

모드를 'a'로 두고 file.write()를 하면 된다.


1.4.3. 여러 줄 한번에 쓰기

patient_list = ["김환자(고혈압)\n", "이환자(당뇨병)\n", "박환자(감기)\n"]  

with open('patient_list.txt', 'w', encoding='utf-8') as file:
    file.writelines(patient_list)

위와 같이 여러 줄로 미리 작성된 것을 한번에 쓰고 싶으면 file.writelines()를 쓰면 된다.


1.4.4. 리스트 데이터를 파일로 저장

medicines = ['혈압약', '당뇨약', '감기약', '진통제']  
with open('medicine_list.txt', 'w', encoding='utf-8') as file:
    for medicine in medicines:               
        file.write(f"{medicine}\n")    # for문을 돌며 줄바꿈 해가며 작성됨

1.5. 파일 경로 지정

앞서 파일을 불러올 때 아래와 같이 불러온다고 했다.

with open('파일명을 포함한 파일이 존재하는 위치', '모드', encoding='utf-8') as file:
작업 내용

이 때 '파일명을 포함한 파일이 존재하는 위치'를 처음 작성해주어야 하는데
위의 예시들에서는 내가 작업하고자하는 파일이 현재 폴더에 저장되어있다는 전제하에
파일명만 작성해주었다.

1.5.1. 하위 폴더를 생성하고, 백업 저장하기

current_folder = "patient_records.txt"          
sub_folder = "backup/patient_backup.txt"

# 현재 폴더에 환자 기록 저장
with open(current_folder, 'w', encoding='utf-8') as file:
    file.write("김환자 - 고혈압\n이환자 - 당뇨병\n")

# 하위 폴더에 백업 저장
import os
os.makedirs("backup") # backup폴더 생성

with open(sub_folder, 'w', encoding='utf-8') as file:
    file.write("백업 완료: 2024-03-15\n")




2. 예외처리 ⚠️

예외 처리는 프로그램을 사용하는 동안 발생할 수 있는 오류를 적절히 처리하여
시스템 안정성을 보장하기 위해 마련하는 보험같은 개념이다.

2.1. try-except 구문

try 블록에서 오류가 발생하면 except 블록이 실행되는 구조로
예외가 발생할 수 있는 코드를 안전하게 실행시킬 수 있도록 해주며 기본 문법은 아래와 같다.

try:
    # 오류가 발생할 수 있는 코드
    
except 특정 예외타입:
    # 오류가 발생했을 때 실행할 코드

except Exception as e:
    # 예외 객체를 e로 받아서 사용

이건 과제를 풀며 작성한 코드를 보면 더 이해가 빠르다.

[캡쳐 1-1. 과제 요구 사항]


[캡쳐 1-2. 작성한 코드 비교]

추가로 finally블록은 예외 발생 여부와 관계 없이 항상 실행되는 코드 블록으로써
반드시 실행되어야 하는 작업에 사용해줄 수 있다.


2.2. 특정 예외타입의 종류

예외 타입발생 원인해결 방법
FileNotFoundError파일이 존재하지 않음파일 경로 확인, 새 파일 생성
PermissionError파일 접근 권한 없음권한 요청, 다른 위치 사용
IsADirectoryError파일 대신 폴더를 열려고 함올바른 파일 경로 지정
ValueError데이터(값)이 잘못되었음데이터 수정하여 입력
UnicodeDecodeError잘못된 인코딩으로 읽기UTF-8 인코딩 지정
OSError운영체제 관련 오류시스템 상태 확인
IOError입출력 일반 오류파일 상태 및 연결 확인

* raise를 사용하면 일부러 에러를 발생시킬 수 있다.([캡쳐 1-2]참고)



예외 처리를 잘 해 줄수록 보다 안정성 있게 코드를 실행시킬 수 있다.
그리고 그 능력은 직접 에러를 경험하면서 인사이트가 넓어진다.
내가 과제를 하며 다른 에러의 가능성을 생각하지 못했던 것처럼 말이다.

이번 내용을 배우고 과제를 하며
좀 더 많은 경험을 쌓아서 시야를 넓혀야겠다는 생각을 하게 되었다.

profile
R&D 분야의 경험을 토대로 커리어 확장에 도전중인 개발꿈나무입니다.

0개의 댓글