IT프로그래밍/파이썬

파이썬 파일 읽기 쓰기 : with open으로 주문장을 남기는 방법

MannizDev 2026. 8. 20.

카페 키오스크에 손님 이름을 넣었다고 해 보겠습니다. Python input 사용법input()은 지금 당장 받은 글자입니다. 프로그램을 끄면 그 글자는 화면과 함께 사라집니다.

종이에 적어 둔 주문은 다릅니다. 가게 문을 닫아도 노트는 카운터에 남습니다. 파이썬에서 그 노트가 파일입니다. open()은 노트를 펼치는 동작이고, with는 “다 쓰면 덮어 두기”까지 한 묶음으로 처리합니다.

앞 글 파이썬 try except 사용법에서 손님 입력이 틀려도 가게를 닫지 않게 했습니다. 이번에는 어제 주문을 내일도 읽을 수 있게, 디스크에 남기는 방법을 봅니다.

한글 제목 파이썬 파일 입출력과 with open으로 읽고 쓰기를 보여주는 대표 이미지

없는 노트를 펼치면 프로그램이 멈춥니다

아직 만들지 않은 주문장을 열어 보겠습니다.

print("주문을 불러옵니다.")
notebook = open("없는_주문장.txt", encoding="utf-8")
print("이 줄은 실행되지 않습니다.")
print(notebook.read())

실행하면 첫 문장만 나오고 멈춥니다.

주문을 불러옵니다.
Traceback (most recent call last):
  File "01_missing_file.py", line 2, in <module>
    notebook = open("없는_주문장.txt", encoding="utf-8")
FileNotFoundError: [Errno 2] No such file or directory: '없는_주문장.txt'

없는 텍스트 파일을 열어 FileNotFoundError가 발생한 Python 실행 기록

FileNotFoundError는 “그 이름 파일이 이 폴더에 없다”는 뜻입니다. ValueError가 값 모양 문제였다면, 이번은 찾을 대상이 없는 문제입니다. 파일이 없는데 read()를 하는 줄까지 가지도 못합니다.

그래서 파일을 다루는 코드는 두 가지를 같이 배웁니다. 노트를 펼치고 덮는 방법, 그리고 노트가 없을 때 안내하고 이어 가는 방법입니다.

with는 펼치고, 적고, 알아서 덮습니다

주문 두 줄을 파일에 남긴 뒤, 같은 파일을 다시 읽습니다.

with open("orders.txt", "w", encoding="utf-8") as notebook:
    notebook.write("아메리카노 2\n")
    notebook.write("카페라테 1\n")

with open("orders.txt", encoding="utf-8") as notebook:
    text = notebook.read()

print("주문장 내용 :")
print(text)
print("파일은 닫혔는가 :", notebook.closed)
주문장 내용 :
아메리카노 2
카페라테 1

파일은 닫혔는가 : True

한 줄씩 역할을 보면 이렇습니다.

  • "orders.txt"는 파일 이름입니다. 코드와 같은 폴더에 만들어집니다.
  • "w"는 write, 즉 쓰기 모드입니다. 같은 이름이 있으면 내용을 비우고 다시 적습니다.
  • encoding="utf-8"은 한글을 어떤 규칙으로 저장할지 정합니다.
  • as notebook은 펼친 노트를 notebook이라는 이름으로 쓰겠다는 뜻입니다.
  • write()는 화면에 출력하지 않고 파일에 글자를 넣습니다. \n이 줄바꿈입니다.
  • 모드를 생략하면 읽기("r")입니다. read()는 파일 전체 글자를 한 문자열로 돌려줍니다.

with 블록이 끝나는 순간 파이썬이 파일을 닫습니다. 그래서 closedTrue입니다. open()만 쓰고 close()를 빼면, 적어 둔 내용이 디스크에 다 안 남을 수 있습니다. 공식 문서도 파일은 with로 다루는 쪽을 권합니다.

print()가 손님에게 영수증을 보여 주는 일이라면, write()는 카운터 노트에 남기는 일입니다. 화면에는 안 보여도 파일이 생깁니다.

한 줄은 손님 한 명입니다

주문은 보통 한 줄에 한 건입니다. 전체를 한 덩어리로 읽기보다, 줄마다 처리하는 쪽이 실무에서 더 자주 씁니다.

with open("orders.txt", "w", encoding="utf-8") as notebook:
    notebook.write("아메리카노 2\n")
    notebook.write("카페라테 1\n")
    notebook.write("녹차 1\n")

print("한 줄씩 읽기 :")
with open("orders.txt", encoding="utf-8") as notebook:
    for line in notebook:
        print("받은 주문 :", line.strip())
한 줄씩 읽기 :
받은 주문 : 아메리카노 2
받은 주문 : 카페라테 1
받은 주문 : 녹차 1

for line in notebook는 파일을 리스트로 먼저 만들지 않고, 한 줄씩 꺼냅니다. line에는 줄 끝 \n이 붙어 있으므로 파이썬 문자열 메서드 기초strip()으로 양쪽 공백과 줄바꿈을 뗍니다. 반복 자체는 Python for문 사용법과 같습니다. 이번엔 range() 대신 파일이 순서를 줍니다.

모든 줄을 파이썬 리스트로 받고 싶으면 notebook.readlines()를 쓰면 됩니다. 파일이 아주 크면 메모리에 한꺼번에 올라오므로, 한 줄씩 for가 더 가볍습니다.

w는 새 장, a는 빈 칸에 이어서 적기

같은 파일 이름에 "w"를 두 번 쓰면, 두 번째가 첫 번째를 지웁니다.

with open("today.txt", "w", encoding="utf-8") as notebook:
    notebook.write("아침 주문 : 아메리카노\n")

with open("today.txt", "w", encoding="utf-8") as notebook:
    notebook.write("점심 주문 : 카페라테\n")

with open("today.txt", encoding="utf-8") as notebook:
    print(notebook.read())
점심 주문 : 카페라테

아침 줄이 없습니다. "w"는 새 노트를 꺼내는 것과 같아서, 어제 적은 글을 남기지 않습니다.

뒤에 붙이려면 "a"(append)를 씁니다.

with open("today.txt", "w", encoding="utf-8") as notebook:
    notebook.write("아침 주문 : 아메리카노\n")

with open("today.txt", "a", encoding="utf-8") as notebook:
    notebook.write("점심 주문 : 카페라테\n")

with open("today.txt", encoding="utf-8") as notebook:
    print(notebook.read())
아침 주문 : 아메리카노
점심 주문 : 카페라테

모드만 바꿔도 결과가 갈립니다.

모드 하는 일 파일이 없을 때 이미 있을 때
"r" 읽기 FileNotFoundError 내용을 읽음
"w" 쓰기 새 파일을 만듦 내용을 비우고 다시 씀
"a" 추가 새 파일을 만듦 맨 뒤에 이어 씀

로그처럼 “오늘 일어난 일을 계속 쌓고” 싶으면 "a"입니다. 설정 파일처럼 “지금 값만 한 장에 다시 쓰고” 싶으면 "w"입니다.

한글은 encoding을 같이 적습니다

open()의 기본 인코딩은 운영체제에 따라 다릅니다. Windows에서는 한글 로캘이 cp949인 경우가 많고, 공식 문서는 텍스트 파일에 encoding="utf-8"을 권합니다. 저장할 때와 읽을 때 규칙을 다르게 하면 글자가 깨지거나 UnicodeDecodeError가 납니다.

그래서 이 글의 예제는 읽고 쓸 때 모두 encoding="utf-8"을 붙였습니다. 한글로 주문, 이름, 주소를 남길 때는 이 한 줄을 습관으로 두는 편이 안전합니다.

주문장이 없어도 가게는 닫지 않습니다

없는 파일을 열 때 나는 이름만 except에 적으면, 새 장을 만들고 다음 일을 이어 갈 수 있습니다.

try:
    with open("없는_주문장.txt", encoding="utf-8") as notebook:
        print(notebook.read())
except FileNotFoundError:
    print("주문장이 없습니다. 새 장을 준비합니다.")
    with open("없는_주문장.txt", "w", encoding="utf-8") as notebook:
        notebook.write("아직 주문이 없습니다.\n")

with open("없는_주문장.txt", encoding="utf-8") as notebook:
    print("현재 주문장 :")
    print(notebook.read())
주문장이 없습니다. 새 장을 준비합니다.
현재 주문장 :
아직 주문이 없습니다.

except ValueError로는 이 오류가 잡히지 않습니다. 앞 글에서 except 이름과 실제 오류가 같아야 한다고 본 것과 같습니다. 파일이 없을 때는 FileNotFoundError입니다.

withtry는 역할이 다릅니다. with는 연 파일을 닫는 약속이고, try는 열기 자체가 실패했을 때 안내하는 그물입니다. 둘을 겹치면 “없어도 새 장을 만들고, 열었으면 반드시 덮는다”가 됩니다.

화면이 아니라 노트에 남기면 됩니다

input()은 지금 이 실행에서만 유효합니다. 파일을 쓰면 다음 실행에서도 같은 주문을 다시 읽을 수 있습니다. "w"는 덮어쓰기, "a"는 이어 쓰기, 읽기는 read() 또는 줄 단위 for입니다. 한글은 encoding="utf-8"을 읽고 쓰기에 같이 둡니다.

없는 파일을 읽으면 FileNotFoundError입니다. 프로그램이 꺼지게 두지 않으려면 그 이름만 except에 적습니다.

메뉴 가격처럼 이름과 값을 짝으로 저장하는 방법은 파이썬 딕셔너리 사용법과 이어집니다. 여러 값을 한 함수로 묶어 파일에 쓰는 방법은 파이썬 함수 만들기를 이어서 보면 됩니다.

참고한 공식 문서

댓글

💲 추천 글