
23. 파일 읽기/쓰기 - 데이터를 저장하자
프로그램이 꺼지면 변수에 담아둔 데이터도 사라진다. 데이터를 영구적으로 보관하고 싶다면? 파일에 저장하면 된다. 파일 입출력은 실무에서 가장 자주 쓰는 기능 중 하나다.
open() 함수 - 파일 열기의 기본
파일을 다루려면 먼저 open() 함수로 파일을 열어야 한다.
파일객체 = open("파일이름", "모드")
파일 모드 종류

| 모드 | 설명 | 파일 없을 때 |
|---|---|---|
"r" |
읽기 (Read) | 에러 발생 |
"w" |
쓰기 (Write) — 기존 내용 삭제 | 새로 생성 |
"a" |
추가 (Append) — 기존 내용 뒤에 추가 | 새로 생성 |
"x" |
생성 (eXclusive) — 파일이 이미 있으면 에러 | 새로 생성 |
기본 모드는
"r"(읽기)이다. 생략하면 읽기 모드로 열린다.
파일 쓰기 - write()
기본 쓰기
f = open("hello.txt", "w")
f.write("안녕하세요!\n")
f.write("파이썬 파일 입출력입니다.\n")
f.close() # 반드시 닫아줘야 한다!
write() 메서드로 문자열을 파일에 쓴다. 줄바꿈(\n)은 직접 넣어야 한다.
writelines()로 여러 줄 쓰기
lines = ["첫 번째 줄\n", "두 번째 줄\n", "세 번째 줄\n"]
f = open("multi.txt", "w")
f.writelines(lines)
f.close()
writelines()은 리스트의 각 요소를 이어붙여 쓴다. 줄바꿈은 자동으로 추가되지 않으므로 각 문자열에\n을 포함시켜야 한다.
추가 모드 (append)
# 기존 파일 끝에 내용 추가
f = open("hello.txt", "a")
f.write("새로 추가된 내용!\n")
f.close()
"w" 모드와 달리 "a" 모드는 기존 내용을 보존하고 뒤에 이어 쓴다.
파일 읽기 - read(), readline(), readlines()
read() - 전체 읽기
f = open("hello.txt", "r")
content = f.read() # 파일 전체를 문자열로
print(content)
f.close()
readline() - 한 줄씩 읽기
f = open("hello.txt", "r")
line1 = f.readline() # 첫 번째 줄
line2 = f.readline() # 두 번째 줄
print(line1, end="")
print(line2, end="")
f.close()
readlines() - 전체를 리스트로
f = open("hello.txt", "r")
lines = f.readlines() # ["안녕하세요!\n", "파이썬 파일 입출력입니다.\n", ...]
print(lines)
f.close()
for 문으로 한 줄씩 읽기 (가장 많이 쓰는 방법)
f = open("hello.txt", "r")
for line in f:
print(line, end="") # 이미 \n이 포함되어 있으므로 end="" 사용
f.close()
with 문 - 파일을 안전하게 다루기
매번 close()를 호출하는 건 귀찮고, 실수로 빠뜨리면 문제가 생길 수 있다. with 문을 쓰면 자동으로 닫아준다.
# with 문을 사용하면 블록을 벗어나면 자동으로 close()
with open("hello.txt", "r") as f:
content = f.read()
print(content)
# 여기서 f는 이미 닫힘 — 걱정 없다!
with 문으로 쓰기
with open("output.txt", "w") as f:
f.write("with 문으로 쓰기!\n")
f.write("자동으로 닫아주니 편하다.\n")
실무에서는 거의 항상 with 문을 사용한다. 이유: 예외가 발생해도 파일이 안전하게 닫히기 때문이다.
with 문 비교
# 😐 옛날 방식
f = open("data.txt", "r")
try:
content = f.read()
finally:
f.close()
# 😊 with 문 (권장)
with open("data.txt", "r") as f:
content = f.read()
실전 예시: 메모장 프로그램
def save_memo(filename, memo):
"""메모를 파일에 추가"""
with open(filename, "a", encoding="utf-8") as f:
f.write(memo + "\n")
print("메모가 저장되었습니다!")
def read_memos(filename):
"""저장된 메모 전체 출력"""
try:
with open(filename, "r", encoding="utf-8") as f:
content = f.read()
if content:
print("=== 저장된 메모 ===")
print(content)
else:
print("저장된 메모가 없습니다.")
except FileNotFoundError:
print("아직 메모가 없습니다.")
# 사용 예
save_memo("memos.txt", "우유 사기")
save_memo("memos.txt", "파이썬 공부하기")
read_memos("memos.txt")
encoding="utf-8"을 지정하면 한글이 깨지지 않는다. Windows에서 특히 중요하다.
CSV 파일 다루기
CSV (Comma-Separated Values)는 데이터를 쉼표로 구분하는 파일 형식이다. 엑셀에서도 열 수 있어서 데이터 교환에 많이 쓰인다.
직접 읽기 (기본 방법)
# students.csv 파일 내용:
# 이름,국어,영어,수학
# 김철수,85,90,78
# 이영희,92,88,95
# 박민수,76,82,89
with open("students.csv", "r", encoding="utf-8") as f:
for line in f:
row = line.strip().split(",")
print(row)
# ['이름', '국어', '영어', '수학']
# ['김철수', '85', '90', '78']
# ...
csv 모듈 사용하기
파이썬에는 CSV를 편하게 다루는 csv 모듈이 내장되어 있다.
import csv
# CSV 읽기
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
header = next(reader) # 첫 줄(헤더) 건너뛰기
print(f"과목: {header[1:]}")
for row in reader:
name = row[0]
scores = [int(s) for s in row[1:]]
avg = sum(scores) / len(scores)
print(f"{name}: 평균 {avg:.1f}점")
csv.writer로 쓰기
import csv
students = [
["이름", "국어", "영어", "수학"],
["김철수", 85, 90, 78],
["이영희", 92, 88, 95],
["박민수", 76, 82, 89]
]
with open("result.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
for row in students:
writer.writerow(row) # 한 줄씩 쓰기
# 또는 한번에: writer.writerows(students)
newline=""을 지정하지 않으면 Windows에서 빈 줄이 생길 수 있다.
csv.DictReader - 딕셔너리로 읽기
import csv
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['이름']}: 국어 {row['국어']}, 영어 {row['영어']}")
DictReader는 첫 줄을 헤더(키)로 사용해서 각 행을 딕셔너리로 만들어준다. 컬럼 이름으로 접근할 수 있어서 훨씬 직관적이다.
파일 경로 다루기
상대 경로 vs 절대 경로
# 상대 경로 — 현재 작업 디렉토리 기준
open("data.txt", "r")
open("data/scores.csv", "r")
# 절대 경로 — 전체 경로
open("C:/Users/user/Documents/data.txt", "r")
open("/home/user/data.txt", "r")
os.path로 경로 다루기
import os
# 파일 존재 확인
if os.path.exists("data.txt"):
print("파일이 있습니다!")
# 경로 합치기
path = os.path.join("data", "students.csv")
print(path) # data/students.csv (OS에 맞게)
# 파일 이름만 추출
print(os.path.basename("/home/user/data.txt")) # data.txt
# 폴더만 추출
print(os.path.dirname("/home/user/data.txt")) # /home/user
직접 해보기
문제 1. 사용자로부터 이름과 나이를 입력받아 profiles.txt에 저장하는 코드를 작성해보자. 여러 번 실행해도 기존 내용이 유지되어야 한다.
문제 2. 파일에서 숫자를 읽어 합계와 평균을 계산하는 함수를 작성해보자. numbers.txt에 한 줄에 하나씩 숫자가 적혀 있다고 가정한다.
문제 3. 학생 성적 데이터를 CSV 파일에 저장하고, 다시 읽어서 평균 점수가 가장 높은 학생을 찾아보자.
문제 4. 텍스트 파일의 글자 수, 단어 수, 줄 수를 세는 count_file_stats(filename) 함수를 작성해보자.
정답 보기
# 문제 1 - 프로필 저장
name = input("이름: ")
age = input("나이: ")
with open("profiles.txt", "a", encoding="utf-8") as f:
f.write(f"{name}, {age}세\n")
print("저장 완료!")
# 저장된 내용 확인
with open("profiles.txt", "r", encoding="utf-8") as f:
print(f.read())
# 문제 2 - 숫자 합계와 평균
def sum_and_avg(filename):
with open(filename, "r") as f:
numbers = []
for line in f:
line = line.strip()
if line:
numbers.append(float(line))
total = sum(numbers)
avg = total / len(numbers) if numbers else 0
return total, avg
# numbers.txt에 10, 20, 30, 40, 50이 있다면
# total, avg = sum_and_avg("numbers.txt")
# print(f"합계: {total}, 평균: {avg}")
# 문제 3 - CSV 성적 관리
import csv
# 저장
students = [
["이름", "국어", "영어", "수학"],
["김철수", 85, 90, 78],
["이영희", 92, 88, 95],
["박민수", 76, 82, 89]
]
with open("scores.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerows(students)
# 읽기 + 최고 성적 찾기
best_name = ""
best_avg = 0
with open("scores.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
avg = (int(row["국어"]) + int(row["영어"]) + int(row["수학"])) / 3
print(f"{row['이름']}: 평균 {avg:.1f}")
if avg > best_avg:
best_avg = avg
best_name = row["이름"]
print(f"\n최고 성적: {best_name} ({best_avg:.1f}점)")
# 문제 4 - 파일 통계
def count_file_stats(filename):
with open(filename, "r", encoding="utf-8") as f:
content = f.read()
chars = len(content)
words = len(content.split())
lines = content.count("\n") + (1 if content and not content.endswith("\n") else 0)
return chars, words, lines
# 사용 예시
# c, w, l = count_file_stats("hello.txt")
# print(f"글자 수: {c}, 단어 수: {w}, 줄 수: {l}")
오늘의 정리
| 항목 | 내용 |
|---|---|
| open() | 파일 열기. 모드: "r" 읽기, "w" 쓰기, "a" 추가 |
| with 문 | with open() as f: — 자동으로 파일을 닫아줌 (권장) |
| 읽기 메서드 | read() 전체, readline() 한 줄, readlines() 리스트 |
| 쓰기 메서드 | write() 문자열 쓰기, writelines() 리스트 쓰기 |
| CSV 모듈 | csv.reader, csv.writer, csv.DictReader로 CSV 파일 처리 |
| encoding | encoding="utf-8" 지정으로 한글 깨짐 방지 |
다음 편 예고: 정규표현식 - 문자열 처리의 끝판왕
이메일 형식이 맞는지, 전화번호에서 숫자만 뽑고 싶을 때, 특정 패턴의 텍스트를 한방에 찾고 싶을 때... 정규표현식이 그 해답이다!
태그: 파이썬 Python 파이썬독학 파일입출력 open read write with문 CSV 파이썬기초 IT교육
'Python' 카테고리의 다른 글
| 25. 가상환경과 프로젝트 관리 - 프로처럼 세팅하기 (1) | 2026.02.22 |
|---|---|
| 24. 정규표현식 - 문자열 처리의 끝판왕 (0) | 2026.02.22 |
| 22. 에러와 예외처리 - 프로그램이 죽지 않게 (0) | 2026.02.22 |
| 21. 모듈과 패키지 - 남이 만든 코드 활용하기 (0) | 2026.02.22 |
| 20. 데코레이터와 제너레이터 - 중급으로 가는 관문 (1) | 2026.02.22 |
댓글