13. 파일 입출력



  • 파일을 열어서 읽고, 쓰고, 덧붙이는 방법
    • open(filename, mode) 내장 함수로 filename 이름을 지닌 file 객체를 얻는다.
    • 얻어진 파일 객체에서 자료를 읽거나, 쓰거나, 덧붙이는 작업 수행
    • 모든 작업이 끝나면 close()를 호출하여 작업 프로세스의 자원 점유 해제

1 파일 입출력 방법


1-1 파일 처리 모드의 종류

  • open 내장 함수의 두번째 인자 mode 설명
    • 두번째 인자 mode 생략시에는 읽기 전용(r) 모드로 설정
Mode 간단 설명 자세한 설명
'r' 읽기 전용 (기본 모드) 파일 객체를 읽기 모드로 생성하고, 파일 포인터를 파일 처음 위치에 놓는다.
'w' 쓰기 전용 새로운 파일을 쓰기 모드로 생성하거나 해당 파일이 이미 존재하면 내용을 모두 없에면서 쓰기 모드로 생성하고, 파일 포인터를 파일 처음 위치에 놓는다.
'a' 파일 끝에 추가 이미 존재하는 파일을 쓰기 모드로 생성하거나 파일이 존재하지 않으면 새롭게 파일을 생성하면서 쓰기 모드로 생성하고, 파일 포인터를 파일의 마지막 위치에 놓는다. 그래서, 이후 작성되는 내용은 파일의 뒷 부분에 추가된다.
  • 이진 파일로 저장을 위해서는 아래 모드 사용
Mode 간단 설명
'rb' 이진 파일 읽기 전용
'wb' 이진 파일 쓰기 전용
'ab' 이진 파일 끝에 추가

1-2 파일 쓰기

In [7]:
import os

print os.getcwd()
/Users/yhhan/git/python-e-learning
In [11]:
s = """Its power: Python developers typically report 
they are able to develop applications in a half
to a tenth the amount of time it takes them to do
the same work in such languages as C."""
f = open('t.txt', 'w')
f.write(s) # 문자열을 파일에 기록
f.close()

1-3 파일 읽기

In [12]:
f = file('t.txt') # f = open('t.txt', 'r')과 동일
s = f.read()
print s
Its power: Python developers typically report 
they are able to develop applications in a half
to a tenth the amount of time it takes them to do
the same work in such languages as C.
  • close()을 마지막에 호출하지 않으면 해당 file 객체가 다른 값으로 치환되거나 프로그램이 종료될 때 자동으로 close()가 불리워진다.
    • 하지만 명시적으로 close()를 호출하는 것을 권장함

1-4 라인 단위로 파일 읽기

  • 총 4가지 방법 존재
    • 파일 객체의 반복자(iterator) 이용하기
      • 파일 객체의 반복자는 각 라인별로 내용을 읽어오도록 설정되어 있음
      • 파일을 라인별로 읽는 방법 중 가장 효과적임
    • readline(): 한번에 한줄씩 읽는다.
    • readlines(): 파일 전체를 라인 단위로 끊어서 리스트에 저장한다.
    • xreadlines(): readlines()과 유사하지만 파일 전체를 한꺼번에 읽지 않고, 상황별로 필요한 라인만 읽는다. 대용량의 파일을 for 문 등으로 라인 단위로 읽을 때 효율적이다.
  • 파일 객체의 반복자 사용
In [13]:
f = open('t.txt')
i = 1
for line in f:
    print i, ":", line,
    i += 1
f.close()
1 : Its power: Python developers typically report 
2 : they are able to develop applications in a half
3 : to a tenth the amount of time it takes them to do
4 : the same work in such languages as C.
  • readline() 사용
In [14]:
f = open('t.txt')
line = f.readline()
i = 1
while line:
    print i, ":", line,
    line = f.readline()
    i += 1
f.close()
1 : Its power: Python developers typically report 
2 : they are able to develop applications in a half
3 : to a tenth the amount of time it takes them to do
4 : the same work in such languages as C.
  • readlines() 사용
    • 각 라인을 모두 읽어서 메모리에 리스트로 저장함
In [15]:
f = open('t.txt')
print f.readlines()
print

f.seek(0)
i = 1
for line in f.readlines():
    print i, ":", line,
    i += 1
f.close()
['Its power: Python developers typically report \n', 'they are able to develop applications in a half\n', 'to a tenth the amount of time it takes them to do\n', 'the same work in such languages as C.']

1 : Its power: Python developers typically report 
2 : they are able to develop applications in a half
3 : to a tenth the amount of time it takes them to do
4 : the same work in such languages as C.
  • xreadlines() 사용
In [18]:
f = open('t.txt')
print f.xreadlines()
print

f.seek(0)
i = 1
for line in f.xreadlines():
    print i, ":", line,
    i += 1
f.close()
<open file 't.txt', mode 'r' at 0x10ddbfa50>

1 : 0123456789abcdef

1-5 라인 단위로 파일 쓰기

  • writelines(): 리스트 안에 있는 각 문자열을 연속해서 파일로 출력한다.
In [20]:
lines = ['first line\n', 'second line\n', 'third line\n']
f = open('t1.txt', 'w')
f.writelines(lines)
f.close()

f = open('t1.txt')
f.seek(0)
print f.read()
f.close()
first line
second line
third line

  • write() 이용하여 여러 문자열을 각 라인별로 파일로 출력하는 방법
In [2]:
lines = ['first line', 'second line', 'third line']
f = open('t1.txt', 'w')
f.write('\n'.join(lines))
f.close()

f = open('t1.txt')
f.seek(0)
print f.read()
f.close()
first line
second line
third line
  • 텍스트 파일 t.txt의 단어(공백으로 분리된 문자열) 수를 출력하는 방법
In [40]:
f = open('t.txt')
s = f.read()
n = len(s.split())
print n
f.close()
35

1-6 기존 파일에 내용 추가

In [23]:
f = open('removeme.txt', 'w') # 파일의 생성
f.write('first line\n')
f.write('second line\n')
f.close()
In [24]:
f = open('removeme.txt', 'a') # 파일 추가 모드로 오픈
f.write('third line\n')
f.close()

f = open('removeme.txt')      # 파일 읽기
print f.read()
first line
second line
third line

1-7 파일 내 임의 위치로 접근

  • 파일 포인터 (pointer)
    • 파일 내에서 현재 위치를 가리키고 있음
  • 파일 접근 방법
    • 순차 접근 (기본 방식): 파일을 앞에서 부터 순차적으로 읽고 쓰는 방식
    • 임의 접근: 파일 내 임의 위치에서 읽고 쓰는 방식
      • 임의 접근을 위한 file 객체 포인터 (pointer) 관련 메소드
        • seek(n): 파일의 가장 첫번째 위치에서 n번째 바이트로 포인터 이동
        • tell(): 파일 내 현재 포인터 위치를 반환
In [17]:
name = 't.txt' 
f = open(name, 'w+')   # 읽고 쓰기로 오픈, 단, 파일이 이미 존재한다면 기존 파일은 없어지고 다시 생성된다.
s = '0123456789abcdef'
f.write(s)

f.seek(5)       # 시작부터 5바이트 포인터 이동
print f.tell()  # 현재 위치 돌려줌
print f.read(1) # 1문자 읽기
print f.tell()
print
5
5
6


2 표준 출력 방향 전환


  • sys 모듈의 표준 입출력 관련 객체
    • sys.stdout: 표준 출력
    • sys.stderr: 표준 에러 출력
    • sys.stdin: 표준 입력
  • 예를 들어, sys.stdout을 파일 객체로 변환하면 모든 표준 출력(print 출력)은 해당 파일로 저장된다.

2-1 표준 출력을 파일로 저장하기

In [1]:
import sys

f = open('t.txt', 'w')
stdout = sys.stdout   # 표준 출력 저장해 두기
sys.stdout = f        # 파일 객체로 표준 출력 변경
print 'Sample output'
print 'Good'
print 'Good'
f.close()
sys.stdout = stdout   # 필요하면 표준 출력 원상 복구
In [17]:
f = open('t.txt')
print f.read()
Sample output
Good
Good
  • print를 직접 이용하여 출력을 다른 객체로 전환하기
In [14]:
print >> sys.stderr, "Warning, action field not supplied"
Warning, action field not supplied
  • 동일 방법으로 표준 출력(print)을 파일 객체로 전환
In [6]:
f = open('t.txt', 'w')
print >> f, 'spam string'
f.close()

f = open('t.txt')
print f.read()
f.close()
spam string

2-2 StringIO 모듈 사용하기

  • StringIO 모듈의 StringIO 클래스 객체
    • 파일 객체처럼 입출력 가능한 문자열 객체
    • StringIO에 지원되는 메소드는 파일 객체가 지원하는 메소드와 거의 동일하다.
    • getvalue() 메소드
      • 현재까지 담아 놓은 전체 내용을 반환한다.
In [29]:
import StringIO

f = StringIO.StringIO()
f.write("abc")
f.seek(0)
s = f.read()
print s
print

s2 = f.getvalue()
print s2
abc

abc
  • 표준 출력으로 문자열 객체에 내용 작성하기
In [30]:
import sys
import StringIO

stdout = sys.stdout    # 표준 출력 저장해 두기
sys.stdout = f = StringIO.StringIO()  

print type(f)
print 'Sample output'
print 'Good'
print 'Good'

sys.stdout = stdout
In [31]:
s = f.getvalue()

print 'Done-------'
print s
Done-------
<type 'instance'>
Sample output
Good
Good


3 파일로의 지속 모듈


  • 지속성(Persistence)
    • 프로그램 내에 생성된 각종 객체들을 해당 프로그램 종료 이후에도 존재하게 만들고, 그것들을 동일한 또는 다른 프로그램에서 사용하는 기능
  • 지속성 기능을 지원하는 모듈
    • DBM 관련 모듈
      • anydbm, dbm, gdbm, dbhash, dumbdbm
      • anydbm: 시스템에서 사용가능한 모듈 중 가장 최적의 모듈을 반환함
        • 기본적으로 dumbdbm을 반환한다
        • 사전 자료형을 사용하는 것과 동일한 방법으로 사용
    • pickle 모듈
      • 파이썬의 객체를 저장하는 일반화된 지속성 모듈
      • 파이썬의 기본 객체뿐만 아니라 사용자 정의의 복잡한 객체도 저장 가능
      • 기본적으로 텍스트 모드로 저장하지만 이진 모드로도 저장 가능
  • 피클링(pickling) 모듈 사용하기
In [6]:
import pickle

phone = {'tom':4358382, 'jack':9465215, 'jim':6851325, 'Joseph':6584321}
List = ['string', 1234, 0.2345]
Tuple = (phone, List) # 리스트, 튜플, 사전의 복합 객체

f = open('pickle.txt', 'w') # 파일 객체를 얻는다.

pickle.dump(Tuple, f) # 파일로 출력(pickling), 복합 객체 출력 
f.close() 

f = open('pickle.txt')     
                      
x,y = pickle.load(f) # 파일에서 읽어오기. 튜플의 내용을 x, y에 받는다.
print x # 사전
print y # 리스트
{'jim': 6851325, 'Joseph': 6584321, 'jack': 9465215, 'tom': 4358382}
['string', 1234, 0.2345]
In [5]:
import pickle

class Simple: # 가장 단순한 클래스를 정의
    pass

s = Simple() # 인스턴스 객체 생성
s.count = 10 # 인스턴스 이름 공간에 변수 생성

f = open('pickle2.txt', 'w')
pickle.dump(s, f) # 인스턴스 저장
f.close()

f = open('pickle2.txt')
t = pickle.load(f) # 인스턴스 가져오기
print t.count
10

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일