(본 글은 04-3 파일 읽고 쓰기 - 점프 투 파이썬 (wikidocs.net) 보고 혼자 공부하며 정리한 글입니다. 거의 복붙이예요. 저작권 문제 시 삭제하겠습니다.)
04-3 파일 읽고 쓰기
우리는 이 책에서 이제까지 값을 입력받을 때는 사용자가 직접 입력하는 방식을 사용했고 출력할 때는 모니터 화면에 결괏값을 출력하는 방식으로 프로그래밍해 왔다. 하지만 ...
wikidocs.net
우리는 지금까지 값을 '입력'받을 때는 사용자가 직접 입력하는 방식을 사용했고, '출력'할 때는 모니터 화면에 결괏값을 출력하는 방식으로 프로그래밍해왔다. 하지만 입출력 방법에는 이것만 있는 것이 아니다. 이번에는 파일을 통한 입출력 방법에 대해 알아보자. 여기서는 파일을 새로 만든 다음 프로그램이 만든 결괏값을 새 파일에 저장해 볼 것이다. 또 파일에 적은 내용을 읽고, 새로운 내용을 추가하는 방법도 알아보자.
다음 소스코드를 에디터로 작성해서 저장한 후 실행해보자. 프로그램을 실행한 디렉터리에 새로운 파일이 하나 생성된 것을 확인할 수 있을 것이다.
f = open("new_file.txt", 'w')
f.close()

파일을 생성하기 위해 우리는 파이썬 내장 함수인 open을 사용했다. open 함수는 다음과 같이 "파일 이름"과 "파일 열기 모드"를 입력값으로 받고, 결괏값으로 파일 객체를 돌려준다.
파일 객체 = open("파일 이름", "파일 열기모드")
파일 열기 모드에는 다음과 같은 것이 있다.
| 파일 열기모드 | 설명 |
| r(read) | 읽기 모드 - 파일을 읽기만 할 때 사용 |
| w(write) | 쓰기 모드 - 파일에 내용을 쓸 때 사용 |
| a(add) | 추가 모드 - 파일의 마지막에 새로운 내용을 추가할 때 사용 |
언뜻 보면 쓰기모드(w)와 추가 모드(a)가 비슷해보인다. 과연 무슨 차이일까? 파일을 쓰기모드(w)로 열면 해당 파일이 이미 존재할 경우, 기존에 존재하던 내용이 모두 사라지고, 해당 파일이 존재하지 않으면 새로운 파일이 생성된다. 하지만 추가 모드(a)로 파일을 열면 기존에 존재하던 내용이 사라지지 않고, 기존의 내용에 더해 내용이 추가된다. 그리고 파일이 만약 존재하지 않는다면 파일을 만드는 것은 동일하다.
만약 new_file.txt를 C:/doit 디렉터리에 생성하고 싶다면 다음과 같이 작성해야한다.
f = open("C:/doit/new_file.txt", 'w')
f.close()
이전 예제처럼 단순히 파일 이름만 넣어 open 함수를 사용하게 되면 파이썬 main 함수가 존재하는 디렉터리에 파일이 생성되는 반면 위와 같이 구체적인 주소를 넣어서 원하는 위치에 파일이 생성되게 할 수 있는 것을 알 수 있다.
그럼 open 함수 밑에 f.close() 역할은 무엇일까? f.close()는 열려 있는 파일 객체를 닫아주는 역할을 한다. 사실 이 문장은 생략해도 크게 문제가 되지 않는다. 프로그램이 종료할 때 파이썬 프로그램이 열려있는 파일의 객체를 자동으로 닫아주기 때문이다. 하지만 close()를 사용해서 열려있는 파일을 직접 닫아주는 것이 좋다. 쓰기모드로 열었던 파일을 닫지 않고 다시 사용하려고 하면 오류가 발생하기 때문이다.
파일 경로와 슬래시(/)
파이썬 코드에서 파일 경로를 ㅍ시할 때 "C:/doit/new_file.txt"처럼 슬래시(/)를 사용할 수 있다. 만약 역슬래시(\)를 사용한다면 "C:\\doit\\new_file.txt"처럼 역슬래시 2개를 사용하거나 r"C:\doit\new_file.txt"와 같이 문자열 앞에 r 문자(Raw String)을 덧붙여 사용해야한다. 왜냐하면 "C:\note\test.txt"처럼 파일 경로에 \n과 같은 이스케이프 문자가 있을 경우 줄바꿈 문자로 해석돼 의도했던 파일 경로와 달라지기 때문이다.
위 예에서는 파일을 쓰기모드로 열었지만 아무것도 안 썼다. 이번엔 파일에 직접 써보자
f=open("new_file.txt",'w')
for i in range(1,11):
f.write("%d번째 줄입니다\n"%i)
f.close()
1번째 줄입니다
2번째 줄입니다
3번째 줄입니다
4번째 줄입니다
5번째 줄입니다
6번째 줄입니다
7번째 줄입니다
8번째 줄입니다
9번째 줄입니다
10번째 줄입니다
new_file.txt 파일을 열어보면 다음과 같이 출력되어 있는 것을 확인할 수 있을 것이다. 우리가 프롬프트창에 결과를 출력했을 때 코드를 어떻게 작성했는지 살펴보며 비교해보자.
for i in range(1,11):
print("%d번째 줄입니다" %i)
1번째 줄입니다
2번째 줄입니다
3번째 줄입니다
4번째 줄입니다
5번째 줄입니다
6번째 줄입니다
7번째 줄입니다
8번째 줄입니다
9번째 줄입니다
10번째 줄입니다
무엇이 다른가?
파일 객체가 있고 없고의 유무가 있고, 각각 f.write()와 print()함수를 사용한다는 것이 차이가 있다. f.write() 함수는 print() 함수와 달리 문장 끝에 '\n'을 포함하고 있지 않기에 적어주어야 줄바꿈된 문장을 파일로 내보낼 수 있다.

new_file.txt를 열어보면 다음과 같이 문장이 출력되어 있음을 볼 수 있다.
파이썬에는 외부 파일을 읽어 들여 프로그램에 사용할 수 있는 여러 방법이 있다. 이번에는 그 방법을 자세히 알아보자.
첫번째 방법은 readline 함수를 이용하는 것이다. 다음 예를 보자.
f=open("new_file.txt","r")
line=f.readline()
print(line)
1번째 줄입니다.
위 예는 파일을 f.open("new_file.txt", 'r')로 읽기 모드로 연 후 readline()을 사용해 파일의 첫번째 줄을 읽어 출력하는 경우이다.
만약 모든 줄을 출력하고 싶다면 다음과 같이 하면 된다
f=open("new_file.txt","r")
while True:
line=f.readline()
if line:print(line, end="")
else: break
f.close()
1번째 줄입니다
2번째 줄입니다
3번째 줄입니다
4번째 줄입니다
5번째 줄입니다
6번째 줄입니다
7번째 줄입니다
8번째 줄입니다
9번째 줄입니다
10번째 줄입니다
while True: 문을 통해 파일을 계속 한 줄씩 읽어들인다. 그러다 읽을 줄이 없어 line=False가 되면 break를 수행한다.
print문에 end=""없이 출력하면 각 줄 사이에 한 줄의 간격이 생기게 되는데 이는 각 줄의 끝에 "\n" 문자가 포함되어 있고 print의 "\n"이 중복되어 두 번 줄바뀜이 일어나기 때문이다.
3-2 readlines 함수 사용하기
두번째 방법은 readlines 함수를 사용하는 방법이다. 다음 예를 보자.
f=open("new_file.txt",'r')
lines=f.readlines()
for line in lines:
print(line,end="")
f.close
1번째 줄입니다
2번째 줄입니다
3번째 줄입니다
4번째 줄입니다
5번째 줄입니다
6번째 줄입니다
7번째 줄입니다
8번째 줄입니다
9번째 줄입니다
10번째 줄입니다
readline 함수는 파일의 모든 줄을 읽어 각 줄을 요소로 갖는 리스트를 반환한다. 따라서 위 예에서 lines는 리스트 ['1번째 줄입니다.\n', '2번째 줄입니다.\n' ..., '10번째 줄입니다\n'\가 된다.
줄 바꿈(\n) 문자 제거하기
파일을 읽을 때 줄바꿈(\n)문자를 제거하고 사용해야하는 경우가 많다. 다음처럼 strip 함수를 사용하면 줄바꿈 문자를 제거할 수 있다.
f=open("new_file.txt",'r') lines=f.readlines() for line in lines: line=line.strip() print(line) f.close() 1번째 줄입니다 2번째 줄입니다 3번째 줄입니다 4번째 줄입니다 5번째 줄입니다 6번째 줄입니다 7번째 줄입니다 8번째 줄입니다 9번째 줄입니다 10번째 줄입니다
세번째 방법은 read 함수를 사용하는 것이다. 다음 예를 보자.
f = open("C:/doit/new_file.txt", 'r')
data = f.read()
print(data)
f.close()
f.read()는 파일의 전체를 문자열로 돌려준다. 따라서 위 예의 data는 파일의 전체 내용이다.
쓰기 모드('w')로 파일을 열 때 이미 존재하는 파일을 열면 그 파일의 내용이 모두 사라지게 된다. 하지만 원래 있던 값을 유지하면서 단지 새로운 값만 추가해야할 경우도 있다. 이런 경우 파일을 추가모드('a')로 열면 된다. 다음 예를 보자.
f=open("new_file.txt",'a')
for i in range(11,20):
f.write("%d번째 줄입니다\n" %i)
f.close()
1번째 줄입니다
2번째 줄입니다
3번째 줄입니다
...
16번째 줄입니다
17번째 줄입니다
18번째 줄입니다
19번째 줄입니다
기존 "1~10번째 줄입니다"라고 적혀있던 new_file.txt에 11~20번째 줄이 추가된 것을 확인해 볼 수 있다. 이는 추가모드(a)로 열었기 때문에 기존 파일의 내용을 유지한 채 결괏값을 추가로 적을 수 있었다.
f = open("life_python.txt", 'w')
f.write("Life is too short, you need python")
f.close()
지금까지는 파일을 열면 위와 같은 방식으로 파일을 열고 닫아야했다.
파일을 열면 항상 close()해주는 것이 좋다. 하지만 파일을 열고 닫는 것을 자동으로 처리할 수 있는 방법이 있다. 파이썬의 with문이 그런 역할을 해준다. 다음 예를 보자.
with open("life_python.txt", 'w') as f:
f.write("Life is too short, you need python")
이렇게 하면 with 블록을 벗어나는 순간 파일 객체 f가 자동으로 close되어 편리하다.
[sys 모듈로 매개변수 주기]
명령 프롬프트(DOS)를 사용해본 사람이라면 다음과 같은 명령어를 사용해봤을 것이다.
위 type 명령어는 바로 뒤에 적힌 파일 이름을 인수로 받아 그 내용을 출력해주는 명령 프롬프트 명령어이다. 대부분의 명령 프롬프트 명령어는 다음과 같이 명령행(명령 프롬프트 창)에서 매개변수를 직접 주어 프로그램을 실행하는 방식이다. 이러한 기능을 파이썬 프로그램에도 적용할 수 있다.C:\> type a.txt
명령 프롬프트 명령어 [인수1, 인수2 ...]
파이썬에서는 sys 모듈을 사용하여 매개변수를 직접 줄 수 있다. sys 모듈을 사용하려면 아례 예의 import sys처럼 import 명령어를 사용해야 한다.
import sys args= sys.argv[1:] for i in args: print(i)
위 예는 입력받은 인수를 for문을 이용해 차례대로 하나씩 출력하는 예이다. sys 모듈의 argv는 명령 창에서 입력한 인수를 의미한다. 즉 다음과 같이 입력했다면 argv[0]은 파일이름 sys1.py가 되고, argv[1]부터는 뒤에 따라오는 인수가 차례로 argv의 요소가 된다.
위 프로그램을 C:\doit 디렉터리에 저장한 후 매개변수를 함께 주어 실행하면 다음과 같은 결괏값을 얻을 수 있다.sys1.py aaa bbb ccc argv[0] argv[1] argv[2] argv[3]
수고하셨습니다.
| [Python, 연습문제] 함수, 사용자 입출력, 파일 읽고 쓰기 (0) | 2022.05.29 |
|---|---|
| [Python] 사용자 입력과 출력 (0) | 2022.05.28 |
| [Python] 함수 (0) | 2022.05.28 |
| [N141] Vector (0) | 2022.05.26 |
| [Python] [조건, 반복문] if, for, while문 연습문제 (0) | 2022.05.25 |