파일 사용하기
- -
Unit 27. 파일 사용하기
프로그래밍에서 중요한 축을 차지하는 부분이 파일 처리입니다. 이번에는 파일에서 문자열을 읽고 쓰는 방법과 파이썬 객체를 파일에 읽고 쓰는 방법을 알아보겠습니다.
27.1 파일에 문자열 쓰기, 읽기
이제부터 파일에 문자열을 써서 파일을 만든 뒤에 만든 파일을 읽는 순서로 진행하겠습니다.
27.1.1 파일에 문자열 쓰기
파일에 문자열을 쓸 때는 open 함수로 파일을 열어서 파일 객체(file object)를 얻은 뒤에 write 메서드를 사용합니다.
- 파일객체 = open(파일이름, 파일모드)
- 파일객체.write('문자열')
- 파일객체.close()
다음 내용을 IDLE의 소스 코드 편집 창에 입력한 뒤 실행해보세요.
file = open('hello.txt', 'w') # hello.txt 파일을 쓰기 모드(w)로 열기. 파일 객체 반환
file.write('Hello, world!') # 파일에 문자열 저장
file.close() # 파일 객체 닫기
소스 코드를 실행하면 .py 파일이 있는 폴더에 hello.txt 파일이 생성됩니다. 메모장이나 기타 텍스트 편집기를 사용하여 hello.txt 파일을 열어보면 다음과 같이 'Hello, world!' 문자열이 저장된 것을 볼 수 있습니다.
hello.txt
Hello, world!
파일을 사용하기 위해서는 먼저 open 함수로 파일을 열어서 파일 객체를 얻어야 합니다. 다음과 같이 파일 이름은 'hello.txt'로 지정하고, 파일에 내용을 쓸 것이므로 파일 모드를 'w'로 지정해줍니다. 여기서 'w'는 쓰다( write)의 w입니다.
file = open('hello.txt' , 'w' ) # hello.txt 파일을 쓰기 모드(w)로 열기. 파일 객체 반환
이제 파일 객체를 얻었으니 write로 파일에 문자열을 씁니다.
file.write('Hello, world!') # 파일에 문자열 저장
파일 쓰기가 끝났으면 반드시 close로 파일 객체를 닫아줍니다.
file.close() # 파일 객체 닫기
파일에 문자열을 쓰는 과정은 다음과 같습니다.
▼ 그림 27-1 파일에 문자열 쓰기
27.1.2 파일에서 문자열 읽기
이번에는 앞에서 만든 hello.txt 파일의 문자열을 읽어보겠습니다. 파일을 읽을 때도 open 함수로 파일을 열어서 파일 객체를 얻은 뒤 read 메서드로 파일의 내용을 읽습니다. 단, 이때는 파일 모드를 읽기 모드 'r'로 지정합니다.
- 변수 = 파일객체.read()
다음 내용을 IDLE의 소스 코드 편집 창에 입력한 뒤 실행해보세요.
file = open('hello.txt', 'r') # hello.txt 파일을 읽기 모드(r)로 열기. 파일 객체 반환
s = file.read() # 파일에서 문자열 읽기
print(s) # Hello, world!
file.close() # 파일 객체 닫기
실행 결과
Hello, world!
먼저 open을 사용하여 hello.txt 파일을 읽기 모드 'r'로 엽니다. 여기서 'r'은 읽다(read)의 r입니다.
file = open('hello.txt', 'r') # hello.txt 파일을 읽기 모드(r)로 열기. 파일 객체 반환
이제 read의 반환값을 변수에 저장해주면 파일의 내용을 읽을 수 있습니다. 그리고 print로 변수의 값을 출력해보면 'Hello, world!'가 출력됩니다.
s = file.read() # 파일에서 문자열 읽기
print(s) # Hello, world!
마찬가지로 파일 읽기 작업이 끝났다면 close로 파일 객체를 닫아줍니다.
file.close() # 파일 객체 닫기
파일에서 문자열을 읽는 과정은 다음과 같습니다.
▼ 그림 27-2 파일에서 문자열 읽기
27.1.3 자동으로 파일 객체 닫기
파일을 열 때마다 매번 close로 닫으려니 좀 귀찮습니다. 파이썬에서는 with as를 사용하면 파일을 사용한 뒤 자동으로 파일 객체를 닫아줍니다. 다음과 같이 with 다음에 open으로 파일을 열고 as 뒤에 파일 객체를 지정합니다.
with open(파일이름, 파일모드) as 파일객체:
코드
그럼 앞에서 만든 hello.txt 파일을 읽어보겠습니다.
with open('hello.txt', 'r') as file: # hello.txt 파일을 읽기 모드(r)로 열기
s = file.read() # 파일에서 문자열 읽기
print(s) # Hello, world!
실행 결과
Hello, world!
read로 파일을 읽고나서 close를 사용하지 않았습니다. 이처럼 with as를 사용하면 파일 객체를 자동으로 닫아줍니다.
27.2.1 반복문으로 문자열 여러 줄을 파일에 쓰기
앞에서 문자열 한 줄을 파일에 썼는데 문자열 여러 줄은 어떻게 쓰면 될까요? 간단하게 반복문을 사용하면 됩니다.
with open('hello.txt', 'w') as file: # hello.txt 파일을 쓰기 모드(w)로 열기
for i in range(3):
file.write('Hello, world! {0}\n'.format(i))
.py 파일이 있는 폴더의 hello.txt 파일을 열어보면 다음과 같은 내용이 저장되어 있습니다.
Hello, world! 0
Hello, world! 1
Hello, world! 2
파일에 문자열 여러 줄을 저장할 때 주의할 부분은 개행 문자 부분입니다. 'Hello, world! {0}\n'와 같이 문자열 끝에 개행 문자 \n를 지정해주어야 줄바꿈이 됩니다. 만약 \n을 붙이지 않으면 문자열이 모두 한 줄로 붙어서 저장되므로 주의해야 합니다.
27.2.2 리스트에 들어있는 문자열을 파일에 쓰기
이번에는 리스트에 들어있는 문자열을 파일에 써보겠습니다.
- 파일객체.writelines(문자열리스트)
lines = ['안녕하세요.\n', '파이썬\n', '코딩 도장입니다.\n']
with open('hello.txt', 'w') as file: # hello.txt 파일을 쓰기 모드(w)로 열기
file.writelines(lines)
hello.txt
안녕하세요.
파이썬
코딩 도장입니다.
writelines는 리스트에 들어있는 문자열을 파일에 씁니다. 특히 writelines를 사용할 때는 반드시 리스트의 각 문자열 끝에 개행 문자 \n을 붙여주어야 합니다. 그렇지 않으면 문자열이 모두 한 줄로 붙어서 저장되므로 주의해야 합니다.
27.2.3 파일의 내용을 한 줄씩 리스트로 가져오기
그럼 앞에서 만든 hello.txt 파일의 내용을 한 줄씩 읽어보겠습니다. read는 파일의 내용을 읽어서 문자열로 가져오지만 readlines는 파일의 내용을 한 줄씩 리스트 형태로 가져옵니다..
- 변수 = 파일객체.readlines()
with open('hello.txt', 'r') as file: # hello.txt 파일을 읽기 모드(r)로 열기
lines = file.readlines()
print(lines)
실행 결과
['안녕하세요.\n', '파이썬\n', '코딩 도장입니다.\n']
파일의 내용을 한 줄씩 리스트 형태로 가져왔습니다.
27.2.4 파일의 내용을 한 줄씩 읽기
만약 파일의 내용을 한 줄씩 순차적으로 읽으려면 readline을 사용합니다.
- 변수 = 파일객체.readline()
with open('hello.txt', 'r') as file: # hello.txt 파일을 읽기 모드(r)로 열기
line = None # 변수 line을 None으로 초기화
while line != '':
line = file.readline()
print(line.strip('\n')) # 파일에서 읽어온 문자열에서 \n 삭제하여 출력
실행 결과
안녕하세요.
파이썬
코딩 도장입니다.
readline으로 파일을 읽을 때는 while 반복문을 활용해야 합니다. 왜냐하면 파일에 문자열이 몇 줄이나 있는지 모르기 때문입니다. while은 특정 조건이 만족할 때 계속 반복하므로 파일의 크기에 상관없이 문자열을 읽어올 수 있습니다.
readline은 더 이상 읽을 줄이 없을 때는 빈 문자열을 반환하는데, while에는 이런 특성을 이용하여 조건식을 만들어줍니다. 즉, line != ''와 같이 빈 문자열이 아닐 때 계속 반복하도록 만듭니다. 그리고 반복문 안에서는 line = file.readline()과 같이 문자열 한 줄을 읽어서 변수 line에 저장해주면 됩니다.
특히 변수 line은 while로 반복하기 전에 None으로 초기화해줍니다. 만약 변수 line을 만들지 않고 while을 실행하면 없는 변수와 빈 문자열 ''을 비교하게 되므로 에러가 발생합니다. 또는, line을 None이 아닌 ''로 초기화하면 처음부터 line != ''는 거짓이 되므로 반복을 하지 않고 코드가 그냥 끝나버립니다. while을 사용할 때는 이 부분을 주의해주세요.
line = None # 변수 line을 None으로 초기화
while line != '':
문자열을 출력할 때는 print(line.strip('\n')와 같이 strip 메서드로 \n을 삭제했습니다. 왜냐하면 파일에서 읽어온 문자열에는 '안녕하세요.\n'와 같이 \n이 이미 들어있기 때문입니다. 만약 strip('\n')을 생략하면 문자열 한 줄을 출력할 때마다 빈 줄이 계속 출력됩니다. 즉, 문자열 안에 든 \n과 print가 출력하는 \n 때문에 줄바꿈이 두 번 일어납니다.
27.2.5 for 반복문으로 파일의 내용을 줄 단위로 읽기
while 반복문에서 readline을 사용하니 동작 방식이 조금 헷갈리죠? 파이썬에서는 for 반복문으로 좀 더 간단하게 파일의 내용을 읽을 수 있습니다. 다음은 for 반복문에 파일 객체를 지정하여 줄 단위로 파일의 내용을 읽습니다.
file_for.py
with open('hello.txt', 'r') as file: # hello.txt 파일을 읽기 모드(r)로 열기
for line in file: # for에 파일 객체를 지정하면 파일의 내용을 한 줄씩 읽어서 변수에 저장함
print(line.strip('\n')) # 파일에서 읽어온 문자열에서 \n 삭제하여 출력
실행 결과
안녕하세요.
파이썬
코딩 도장입니다.
for line in file:로 간단하게 파일의 내용을 한 줄씩 읽었습니다. 이렇게 for 반복문에 파일 객체를 지정하면 반복을 할 때마다 파일의 내용을 한 줄씩 읽어서 변수에 저장해줍니다.
파일 객체는 이터레이터입니다. 따라서 변수 여러 개에 저장하는 언패킹(unpacking)도 가능합니다(이터레이터는 'Unit 39 이터레이터 사용하기' 참조).
>>> file = open('hello.txt', 'r')
>>> a, b, c = file
>>> a, b, c
('안녕하세요.\n', '파이썬\n', '코딩 도장입니다.\n')
물론 a, b, c = file과 같이 사용하려면 hello.txt에는 문자열 3줄이 들어있어야 합니다. 즉, 할당할 변수의 개수와 파일에 저장된 문자열의 줄 수가 일치해야 합니다.
파일에서 문자열만 읽고 쓴다면 조금 불편하겠죠? 파이썬은 객체를 파일에 저장하는 pickle 모듈을 제공합니다.
다음과 같이 파이썬 객체를 파일에 저장하는 과정을 피클링(pickling)이라고 하고, 파일에서 객체를 읽어오는 과정을 언피클링(unpickling)이라고 합니다.
▼ 그림 27-3 피클링과 언피클링
27.3.1 파이썬 객체를 파일에 저장하기
그럼 파이썬 객체를 파일에 저장하는 피클링을 해보겠습니다. 피클링은 pickle 모듈의 dump 메서드를 사용합니다.
pickle_dump.py
import pickle
name = 'james'
age = 17
address = '서울시 서초구 반포동'
scores = {'korean': 90, 'english': 95, 'mathematics': 85, 'science': 82}
with open('james.p', 'wb') as file: # james.p 파일을 바이너리 쓰기 모드(wb)로 열기
pickle.dump(name, file)
pickle.dump(age, file)
pickle.dump(address, file)
pickle.dump(scores, file)
소스 코드를 실행하면 .py 파일이 있는 폴더에 james.p 파일이 생성됩니다. 여기서는 확장자를 pickle의 p를 사용했지만 다른 확장자를 사용해도 상관없습니다.
특히 pickle.dump로 객체(값)를 저장할 때는 open('james.p', 'wb')와 같이 파일 모드를 'wb'로 지정해야 합니다. b는 바이너리(binary)를 뜻하는데, 바이너리 파일은 컴퓨터가 처리하는 파일 형식입니다. 따라서 메모장 같은 텍스트 편집기로 열어도 사람이 알아보기 어렵습니다.
참고로 지금까지 사용한 .txt 파일은 사람이 알아보기 쉽도록 만든 파일 형식이며 텍스트(text) 파일이라고 부릅니다.
27.3.2 파일에서 파이썬 객체 읽기
이제 파일에서 파이썬 객체를 읽어오는 언피클링을 해보겠습니다. 언피클링은 pickle 모듈의 load를 사용합니다. 그리고 언피클링을 할 때는 반드시 파일 모드를 바이너리 읽기 모드 'rb'로 지정해야 합니다.
pickle_load.py
import pickle
with open('james.p', 'rb') as file: # james.p 파일을 바이너리 읽기 모드(rb)로 열기
name = pickle.load(file)
age = pickle.load(file)
address = pickle.load(file)
scores = pickle.load(file)
print(name)
print(age)
print(address)
print(scores)
실행 결과
james
17
서울시 서초구 반포동
{'korean': 90, 'english': 95, 'mathematics': 85, 'science': 82}
앞에서 james.p 파일을 저장할 때 pickle.dump를 네 번 사용했습니다. 마찬가지로 파일에서 객체(값)를 가져올 때도 pickle.load를 네 번 사용해야 합니다. 즉, name, age, address, scores 순으로 저장했으므로 가져올 때도 같은 순서로 가져오면 됩니다.
지금까지 파일을 읽고 쓰는 방법을 배웠습니다. 파일 처리는 프로그램을 만들 때 자주 사용되므로 사용 방법을 정확히 익히는 것이 좋습니다.
사실 파일 모드는 조합에 따라 여러 종류가 있습니다. 읽기 'r', 쓰기 'w' 이외에 추가 'a', 배타적 생성 'x'도 있습니다. 추가 모드는 이미 있는 파일에서 끝에 새로운 내용을 추가할 때 사용하고, 배타적 생성 모드는 파일이 이미 있으면 에러(FileExistsError)를 발생시키고 없으면 파일을 만듭니다. 'x'는 베타적 생성(exclusive creation)의 x입니다
또한, 파일의 형식도 함께 지정할 수 있는데, 텍스트 모드
't'와 바이너리 모드 'b'가 있습니다. 이 파일 형식과 읽기, 쓰기 모드를 조합한 텍스트 모드 'rt', 'wt'는 파일을 텍스트 모드로 엽니다. 특히 텍스트 모드는 생략할 수 있어서 그냥 'r', 'w'도 텍스트 모드입니다. 그리고 바이너리 모드 'rb', 'wb' 등은 피클링을 사용하거나 바이너리 데이터를 직접 저장할 때 사용합니다.
그다음에 '+'가 있는데 파일을 읽기/쓰기 모드로 엽니다. 이 모드는 'r+t', 'w+t', 'r+', 'w+', 'r+b', 'w+b' 등으로 조합할 수 있으며 읽기/쓰기 모드인 것은 같지만 파일 처리 방법이 조금씩 다릅니다.
지금까지 나온 파일 모드 조합을 그림으로 정리하면 다음과 같은 구조가 됩니다.
▼ 그림 27-4 파일 모드 조합
'개인공부 > Python' 카테고리의 다른 글
람다 표현식으로 함수 만들기 (0) | 2022.07.29 |
---|---|
함수 사용하기 (0) | 2022.07.28 |
세트 (0) | 2022.07.28 |
python 심사문제 UNIT(25 ~ 35) (0) | 2022.07.28 |
딕셔너리 응용하기 (0) | 2022.07.28 |
소중한 공감 감사합니다