파일 입·출력


 지금까지 공부하면서 짰던 코드들은 프로그램이 종료되면 그대로 종료됩니다. 출력하는 내용이나 코드를 파일로 저장하고 읽어오면 다시 사용할 수 있겠죠? 파일 입·력은 파일을 열어서 쓰고 덧붙이는 방법으로, 다른 프로그래밍 언어와 유사한 형태로 사용합니다. 

- open() 내장 함수


 파일 입출력은 open()이라는 내장함수를 이용하고, 사용이 끝나면 close() 함수로 종료를 해줘야 합니다. close() 쓰지않아도 자동으로 자원을 반납하지만, 코드의 가독성을 위해서라도 써주는게 좋다고합니다. 

 아래 내용은 open() 내장 함수의 세부적인 내용입니다.
----------------------------------------------------------------------------------------

- open("filename",'mode')


- open()함수의 모드

1. 'r'(read) : 생략을 하면 기본적으로 사용되는 모드로, 읽기 전용모드, 파일 포인터를 처음위치에 놓음

2. 'w'(write) : 쓰기모드로 존재하지 않는 파일은 생성하고, 존재하는 파일내용을 모두 지우고 파일포인터를 처음위치에 놓음

3. 'a'(append) : 이미 존재하는 파일 뒤쪽에 내용을 추가, 파일 포인터를 파일의 마지막 위치에 놓음


- 이진 파일로 저장하기 위한 모드

1. rb

2. wb

3. ab

----------------------------------------------------------------------------------------


- 파일 쓰기


 파일을 쓰기에 앞서 현재 작업중인 디렉토리를 알아보는 명령을 알아보겠습니다. os모듈을 임포트하고 getcwd() 함수를 이용하면 현재 작업중인 디렉토리를 확인할 수 있습니다. 파일 쓰게되면 같은 경로에 파일이 생기게됩니다.

----------------------------------------------------------------------------------------

import os

print os.getcwd() # 현재 작업중인 디렉토리를 알아보는 함수

----------------------------------------------------------------------------------------
(실행 결과)

D:\PythonProject\Python\13

----------------------------------------------------------------------------------------


 open() 내장 함수를 이용해 파일 쓰기를 해 보겠습니다. 파일에 쓰기위해서는 write()메소드를 활용 합니다.
----------------------------------------------------------------------------------------
s='''애써 미안한 표정 하지마
싫어진 거잖아 이제 널 떠나줄게
비겁해지는 널 보는 게 아파
내가 갈게 널 보내줄게
-권진아 끝 中에서- '''

f=open('end.txt','w') # 'end.txt' 쓰기모드로 열기
f.write(s) # s 문자열을 파일에 써줌
f.close() # 자원 반납
----------------------------------------------------------------------------------------
 위 코드를 실행하면, 이클립스 콘솔창에는 아무런 내용이 출력되지 않습니다. 작업중인 코드의 경로에 가면 텍스트 파일이 하나 생성되어 있습니다. 


- 파일 읽기


이번에는 이클립스에서 텍스트 파일을 읽어보겠습니다. 파일을 읽을때에는 read()메소드를 이용합니다.

----------------------------------------------------------------------------------------
f=open('end.txt') # 모드 생략 시 읽기 모드
s2=f.read()
print s2
----------------------------------------------------------------------------------------
(실행 결과)
애써 미안한 표정 하지마
싫어진 거잖아 이제 널 떠나줄게
비겁해지는 널 보는 게 아파
내가 갈게 널 보내줄게
-권진아 끝 中에서- 
----------------------------------------------------------------------------------------


- 라인단위로 파일 읽기/쓰기


 파일을 읽을때 라인단위로 읽을 수가 있습니다. 라인 단위로 읽는 방법은 총 4가지가 있습니다.


1. 객체 반복자 사용

 아래와 같이 for-in 문을 이용해서 라인 단위로 출력이 가능합니다. 파일을 라인단위로 읽을때 가장 효율적인 방법이라고 합니다.

----------------------------------------------------------------------------------------
f=open('end.txt')

i=1

for line in f:

    print i,":",line,

    i+=1

f.close()

----------------------------------------------------------------------------------------
(실행 결과)
1 : 애써 미안한 표정 하지마
2 : 싫어진 거잖아 이제 널 떠나줄게
3 : 비겁해지는 널 보는 게 아파
4 : 내가 갈게 널 보내줄게
5 : -권진아 끝 中에서- 
----------------------------------------------------------------------------------------

2. readline() 사용
 readline()을 사용할때에는 while문을 이용합니다. 현재의 파일포인터에서 개행문자까지 읽어줍니다. 아래코드에서는 줄바꿈을 개행문자로 인지합니다. 실행 결과는 위와 동일합니다.
----------------------------------------------------------------------------------------
f=open('end.txt')
line=f.readline()
i=1
while line:
    print i,":",line,
    line=f.readline() # 파일 포인터가 개행문자 다음의 가장 처음에 위치합니다.
    i+=1
f.close()
----------------------------------------------------------------------------------------


3. readlines() 사용

 각 라인을 모두 읽어서 메모리에 리스트 형태로 저장합니다. 라인이 100줄 1000줄이면 메모리를 굉장히 비효율적으로 사용하게 됩니다. 한글이여서 아스키코드로 변화해서 저장되는걸 확인 할 수 있습니다.

----------------------------------------------------------------------------------------
f=open('end.txt')

print f.readlines() # 리스트로 저장

print # 한줄 개행


f.seek(0) # 파일포인터를 처음으로 되돌려줌

i=1


for line in f:

    print i,":",line,

    i+=1

f.close()

----------------------------------------------------------------------------------------
(실행 결과)
['\xec\x95\xa0\xec\x8d\xa8 \xeb\xaf\xb8\xec\x95\x88\xed\x95\x9c \xed\x91\x9c\xec\xa0\x95 \xed\x95\x98\xec\xa7\x80\xeb\xa7\x88\n', '\xec\x8b\xab\xec\x96\xb4\xec\xa7\x84 \xea\xb1\xb0\xec\x9e\x96\xec\x95\x84 \xec\x9d\xb4\xec\xa0\x9c \xeb\x84\x90 \xeb\x96\xa0\xeb\x82\x98\xec\xa4\x84\xea\xb2\x8c\n', '\xeb\xb9\x84\xea\xb2\x81\xed\x95\xb4\xec\xa7\x80\xeb\x8a\x94 \xeb\x84\x90 \xeb\xb3\xb4\xeb\x8a\x94 \xea\xb2\x8c \xec\x95\x84\xed\x8c\x8c\n', '\xeb\x82\xb4\xea\xb0\x80 \xea\xb0\x88\xea\xb2\x8c \xeb\x84\x90 \xeb\xb3\xb4\xeb\x82\xb4\xec\xa4\x84\xea\xb2\x8c\n', '-\xea\xb6\x8c\xec\xa7\x84\xec\x95\x84 \xeb\x81\x9d \xe4\xb8\xad\xec\x97\x90\xec\x84\x9c- ']

1 : 애써 미안한 표정 하지마
2 : 싫어진 거잖아 이제 널 떠나줄게
3 : 비겁해지는 널 보는 게 아파
4 : 내가 갈게 널 보내줄게
5 : -권진아 끝 中에서- 
----------------------------------------------------------------------------------------

4. xreadlines() 사용

 위의 readlines()의 메모리 비효율성을 개선할 수 있는 함수입니다. 리스트가 반환되지 않고, 파일 객체 내용이 찍힙니다. 사용과 실행 결과는 위와 동일합니다.



 그렇다면, 반대로 라인단위로 파일 쓰는건 어떻게 할까요? 이미 위에서 사용했던 write() 함수와 wrtielines() 함수가 있습니다. 라인단위로 파일을 쓸때에는개행문자(\n)를 꼭 써줘야 합니다.

----------------------------------------------------------------------------------------

f=open("end.txt",'a') # 기존 파일에 내용 추가

f.writelines('\n\n')

f.writelines('오늘은 2월 22일 \n')

f.writelines('하루종일 날씨가 흐리다.\n')

f.writelines('얼른 봄이 왔으면 좋겠다.\n')

f.close()


f=open('end.txt')

print f.read()

----------------------------------------------------------------------------------------

(실행 결과)

애써 미안한 표정 하지마

싫어진 거잖아 이제 널 떠나줄게

비겁해지는 널 보는 게 아파

내가 갈게 널 보내줄게

-권진아 끝 中에서- 


오늘은 2월 22일 

하루종일 날씨가 흐리다.

얼른 봄이 왔으면 좋겠다.

----------------------------------------------------------------------------------------


- 파일 내 임의 위치로 접근


 위에서 몇번 언급한 파일포인터는 파일 내에서 현재 위치를 가리키고 있습니다. 이때 seek(5)를 하면 문자열의 5번째 인덱스를 가리키게 됩니다.

 tell()을 사용하면 현재 위치를 돌려주고, read(1)을 사용하게되면 현재 위치에서 문자하나를 읽고나서 파일포인터를 하나 이동합니다.


- 표준 출력 방향 전환


 일반적으로 print 함수를 사용하게되면 문자열을 화면(콘솔)에 출력하게됩니다. sys 모듈의 sys.stdout의 표준출력이 정해져있기 때문인데, 이를 바꿔주면 print함수를 사용하면 바꿔준 형태로 실행이 됩니다.

 아래 코드는 표준출력을 파일에 저장하는것으로 바꾸고 실행 후 다시 되돌리는 코드입니다.

----------------------------------------------------------------------------------------

# -*- coding: utf-8 -*-


import sys

f=open('t.txt','w')

stdout=sys.stdout # 표준출력 저장(백업 개념)

sys.stdout=f


print '테스트 메시지1'

print '테스트 메시지2'

print '테스트 메시지3'


f.close()

sys.stdout=stdout # 다시 원상태로 되돌려줌

----------------------------------------------------------------------------------------

 아래와같이 화면(콘솔)에 출력되는것이 아니라 't.txt'파일에 문자열이 써집니다.


 이밖에도 sys모듈에는 sys.stderr(표준 에러출력)과 sys.stdin(표준 입력)이 있습니다. stderr을 변경하면, 에러메시지 처럼 콘솔창에 빨간색 글씨로 출력이 됩니다.


- StringIO 모듈 사용

 StringIO 모듈의 StringIO 클래스 객체는 사용하면, 파일 객체처럼 입출력 가능한  문자열 객체로, StringIO에 지원되는 메소드는 파일 객체가 지원하는 메소드와 거의 유사합니다. 메소드중에서 getvalue() 메소드가 있는데 현재까지 담아 놓은 전체 내용을 반환하는 메소드입니다.

----------------------------------------------------------------------------------------

import StringIO


f=StringIO.StringIO()

f.write('abc')

f.seek(0)

s=f.read()

print s


f.write('def')

s2=f.getvalue()

print s2

----------------------------------------------------------------------------------------

(실행 결과)

abc

abcdef

----------------------------------------------------------------------------------------


- 파일로의 지속 모듈


- 지속성 : 프로그램 내에 생성된 각종 객체들을 해당 프로그램 종료이후에도 존재하게 만들고, 그것들을 동일한 또는 다른 프로그램에서 사용하는 기능

- 지속성 기능을 지원하는 모듈

DBM 관련 모듈 : anydbm, dbm, gdbm, dbhash, dumbdbm

pickling 모듈 : 파이썬의 객체를 저장하는 일반화된 지속성 모듈


 pickling 모듈이 좀 더 일반적으로 사용한다고해서 pickle모듈만 사용해 봤습니다. 이클립스에서는 에러가 발생해서 Enthought Canopy로 실습을 진행했습니다.

----------------------------------------------------------------------------------------

import pickle


color={'r':'red','g':'green','b':'blue'}

fruits=['banana','apple','grape']

Tuple=(color,fruits)


f=open('pickle.txt','w')


pickle.dump(Tuple,f) # 저장하고자 하는 Tuple을 f에 넣어서 얼림

f.close()


####################################


f=open('pickle.txt')


x,y=pickle.load(f) # dump()와 반대

print x

print y

----------------------------------------------------------------------------------------




출처 한국기술교육대학교 온라인평생교육원 파이썬프로그래밍




'언어 > Python' 카테고리의 다른 글

[파이썬] 디렉토리 다루기  (0) 2017.02.25
[파이썬] 파일 다루기  (0) 2017.02.24
[파이썬] 사전  (0) 2017.02.19
[파이썬] 튜플과 집합자료형  (0) 2017.02.14
[파이썬] 리스트 활용  (4) 2017.02.07

파이썬 개발환경 구축(설치)


 파이썬을 개발하는 여러 환경중에 제가 구축한 환경은 두 가지가 있습니다. Python 전용 통합개발환경(IDE) Enthought Canopy를 설치하는방법과 이클립스에서 설치하는 방법입니다. Canopy를 설치하면 환경설정 관련된 것들이 자동적으로 설정되있어서 그냥 Pyton을 설치하는 것보다 간편하다고 합니다. 하지만, IDE가 부족한 면이있어 이클립스도 같이 활용하는것이 좋다고 합니다.


Enthought Canopy 설치


 첫번째는 Enthought Canopy 설치 방법입니다. Enthought Canopy는 별도의 파이썬 설치 없이 아래 통합개발환경 링크에서 설치를 하면 자동으로 파이썬이 설치됩니다

https://www.enthought.com/products/canopy/


사이트에 들어가서 중앙하단에 보이는 Get Canopy 초록색버튼을 클릭한 후에 free버전을 다운로드 합니다.


기본적으로 설치를 마치고 나면 다음과같은 두 아이콘이 생성됩니다.  


 윈도우 커맨드 창에서 정상적으로 설치가 되었는지 확인을 해보았습니다. 기본적으로 python이라고 입력하면 실행이되며, 대화식으로 print 1+2라는 구문을 입력했을 때 3이 실행되는걸 확인 할 수 있습니다. 종료하는 명령은 exit가 아닌 exit()나 Ctrl+Z를 누르게 되면 종료가 됐습니다. 다음은 ipython을 실행했을때 python과 비슷하지만 색 효과가 있어 좀더 깔끔한 대화환경을 제공할 것 같습니다. 아래 그림은 python과 ipython의 비교 입니다.




- 이클립스에서 파이썬 설치


 두번째 방법은 이클립스에서 설치하는 방법입니다. 저는 이클립스를 기존에 사용해서 바로 설치했는데 없으신 분들은 이클립스를 설치하신 이후에 설치하셔야 합니다.

 설치과정은 아래와 같습니다. 이클립스를 써보신분들은 아실수도 있는 방법입니다. 가장먼저, Help탭에서 Eclipse Marketplace를 클릭합니다.


Eclipse Marketplace 창이뜨면 왼쪽 노란색 부분에 python이라고 입력하고 오른쪽 노란색 Go를 눌러주면 아래와 같은 창이뜨는데 빨간색 부분에있는 PyDev-Python IDE for Eclipse 를 Install 버튼을 눌러 설치해주시면됩니다. 


아래 그림과 같이 기본적으로 체크되어있는대로 설치하시면 됩니다.


설치 도중에 이런 창이뜨는데 체크를 꼭 해주시고 ok 버튼을 눌러야합니다.


아래 두번째 창 역시 Yes를 눌러줘야합니다. 저같은 경우, 재시작이 안되서 이클립스 File탭에서 직접 재시작을 해줬습니다.


설치가 끝나게되면 아래 그림과같이 이클립스 우측 상단에있는 빨간색 부분 아이콘 을 눌러서 PyDev로 바꿔줍니다. 아래 그림처럼 PyDev가 없다면 설치가 정상적으로 이루어지지 않은 것입니다.


PyDev로 바꿔주고 나면 시스템 내 파이썬 인터프리터 검색을 설정해줘야 합니다. 이클립스 Window탭에서 Preferences를 클릭합니다. 


 Preferences창에서 PyDev-Interpreters-Python Interpreter에 들어가서 Quick Auto-Config 버튼을 눌러줍니다. 눌러주면 아래 그림과같이 자동으로 라이브러리 들이 추가가 됩니다.


설치가 끝난 후 예제소스를 실행해보기 위해 프로젝트를 만들고 그안에 디렉토리를 만든후 test.py라는 소스파일을 추가합니다.


간단한 예제 소스를 작성해보았습니다. 소스코드를 작성한뒤 초록색버튼으로 run을 하게되면 실행이되고 아래 콘솔창에 결과가 나옵니다.

-----------------------------------------------------------

# -*- coding: utf-8 -*-

print 1+2

print "안녕하세요"

print 9/5

print 12-32

print 9.0/5.0

print 9/5.0

print 9/5 #정수/정수 = 정수로 출력

-----------------------------------------------------------

# -*- coding: utf-8 -*- 를위에쓰는 이유는 한글을 사용하기위해서 라고합니다. 다른 언어들과는 다르게 print 함수 하나만으로 정수,실수 계산 및 문자열을 출력했습니다. Python에서 주석은 #입니다.


아래는 콘솔창의 결과입니다. 

-----------------------------------------------------------

3

안녕하세요

1

-20

1.8

1.8

1

-----------------------------------------------------------

정수/실수를 했을때는 실수로 계산이되지만, 정수/정수는 1.8임에도 불구하고 정수인 1로 결과가 나왔습니다.


다음 소스는 문자열을 합치는 소스입니다. a와 b에 각각 문자열을 넣고 합칠때에는 "+"를 사용해 합쳤습니다.

-----------------------------------------------------------

a='park'

b='hyeung'

print a+b

-----------------------------------------------------------


아래 소스는 파이썬 버전을 알아보는 소스입니다. sys라는 모듈을 활용해 버전을 확인해 보았습니다. 

-----------------------------------------------------------

import sys

print sys.version

print

print sys.version_info

-----------------------------------------------------------


아래와 같이 2.7.11버전이 설치되있는 걸 확인할 수 있습니다. print함수를 그냥 사용했을때는 아래와같이 한줄 공백이 출력됩니다.

-----------------------------------------------------------

2.7.11 | 64-bit | (default, Jun 11 2016, 11:33:47) [MSC v.1500 64 bit (AMD64)]


sys.version_info(major=2, minor=7, micro=11, releaselevel='final', serial=0)

-----------------------------------------------------------


마지막으로 cal.py라는 소스를 작성해 저장하고 윈도우 커맨드창에서 실행을 해봤습니다. 먼저 아래 소스는 달력을 출력하는 소스입니다. 

-----------------------------------------------------------

import calendar

calendar.prmonth(2016, 12)

-----------------------------------------------------------

실행을 했을때, 콘솔창에 다음과같이 2016년 12월 달력이 출력됐습니다.


저는 D:\PythonProject\Python\01 이경로에 소스파일을 작성해서 커맨드 창에서 경로로 이동을 한뒤에 실행을 했습니다. ipython cal.py로 실행을 하게되면 커맨드 창에서도 똑같이 달력이 출력되는걸 확인할 수 있습니다.



* 출처 : 한국기술교육대학교 온라인평생교육원 파이썬프로그래밍



+ Recent posts