다음을 에디터로 작성해서 실행해 보면 프로그램을 실행한 디렉토리에 새로운 파일이 하나 생성되는 것을 확인할 수 있다.
# file1.py
f = open("새파일.txt", 'w')
f.close()
파일을 생성하기 위해서 우리는 open이란 파이썬 내장 함수를 썼다.
open함수는 다음과 같이 입력으로 파일이름과 파일열기모드라는 것을 받고 리턴값으로 파일 객체를 돌려준다.
파일객체 = open(파일이름, 파일열기모드)
파일 객체와 파일 이름은 프로그래머가 마음대로 바꿀 수 있지만 파일 열기모드는 정해진 값을 사용해야 한다.
파일 열기 모드에는 다음과 같은 것들이 있다.
파일열기 모드
r ( 읽기 모드 ) - 파일을 읽기만 할때
w ( 쓰기 모드 ) - 파일을 쓸때
a ( 추가 모드 ) - 파일의 마지막에 새로운 내용을 추가 시킬때
파일을 쓰기 모드로 열게 되면 해당 파일이 존재할 경우에는 원래있던 내용이 모두 사라지게 되고, 해당 파일이 존재하지 않으면 새로운 파일이 생성된다. 위의 예에서는 없는 파일인 “새파일.txt"를 쓰기 모드로 열었기 때문에 새로운 파일인 "새파일.txt"라는 이름의 파일이 현재디렉토리에 생성되는 것이다.
만약 ”새파일.txt"라는 파일을 C:\Python이란 디렉토리에 생성하고 싶다면 다음과 같이 해야 할 것이다.
f = open("C:\Python\새파일.txt", 'w')
위의 예에서보면 f.close()라는 것이 있는데 이것은 열린 파일 객체를 닫아주는 것이다. 사실 이 문장은 생략해도 된다. 왜냐하면 파이썬 프로그램이 종료할 때 열린 파일 객체를 자동으로 닫아주기 때문이다. 하지만 프로그래머가 직접 열린 파일을 닫아주는 것은 좋은 습관이다.
파일을 쓰기 모드로 열어서 출력값 적기
위의 예에서는 파일을 쓰기모드로 열기만 했지 정작 아무런 것도 쓰지 않았다. 이번에는 작은 프로그램을 만들고 그 출력값을 파일에 적어 보도록 하자.
# file2.py
f = open("새파일.txt", 'w')
for i in range(1, 11):
data = "%d 번째 줄입니다.\n" % i
f.write(data)
f.close()
위의 프로그램을 다음의 프로그램과 비교해 보자.
for i in range(1, 11):
data = "%d 번째 줄입니다.\n" % i
print(data)
두 프로그램의 서로 다른 점은 data를 출력시키는 방법이다. 두 번째 방법은 우리가 지금껏 계속 사용해 왔던 모니터 화면에 출력하는 방법이고 첫 번째 방법은 모니터 화면대신에 파일에 결과값을 적는 방법이다. 차이점이 금방 눈에 들어 올 것이다.
두번째 방법의 print대신에 파일객체 f의 write라는 함수를 이용했을 뿐이다.
첫 번째 예제를 에디터로 작성해서 실행시킨 다음 그 프로그램을 실행시킨 디렉토리를 살펴보면 ”새파일.txt"라는 파일이 생성되었음을 확인 할 수 있을 것이다. 그 파일이 어떤 내용을 담고 있는 지 확인 해 보자. 아마 다음과 같을 것이다.
새파일.txt 의 내용
1 번째 줄입니다.
2 번째 줄입니다.
3 번째 줄입니다.
4 번째 줄입니다.
5 번째 줄입니다.
6 번째 줄입니다.
7 번째 줄입니다.
8 번째 줄입니다.
9 번째 줄입니다.
10 번째 줄입니다.
즉 두 번째 방법을 사용했을 때 모니터 화면에 출력될 내용이 파일에 고스란히 들어가 있는 것을 알 수 있다.
파일을 읽는 여러가지 방법
파이썬에는 파일을 읽는 여러가지 방법이 있다. 그것들에 대해서 자세히 알아보도록 하자.
첫 번째 방법
첫 번째 방법은 readline()을 이용하는 방법이다. 다음의 예를 보자.
# file2.py
f = open("새파일.txt", 'r')
ine = f.readline()
print(line)
f.close()
이전에 만들었던 "새파일.txt"를 수정하거나 지우지 않았다면 위의 프로그램을 실행시켰을 때 “새파일.txt"의 가장 첫 번째 줄을 읽어서 화면에 출력해 줄 것이다. 우선 f.open("새파일.txt", 'r')로 파일을 읽기 모드로 열어서 열린 파일을 나타내는 파일객체 f를 돌려준다. f객체를 이용해서 파일의 한줄을 읽는 파일 객체 관련함수인 readline()을 이용해서 읽은 파일의 첫 번째 줄을 읽어서 line 변수에 대입하고 출력해 보았다.
만약 모든 라인을 읽어서 화면에 출력하고 싶다면 다음과 같은 프로그램을 작성해야 한다.
# file3.py
f = open("새파일.txt", 'r')
while 1:
line = f.readline()
if not line: break
print(line)
f.close()
while 1이란 무한 루프를 이용해서 f.readline()을 이용해서 파일을 계속해서 한 줄씩 읽어 들인다. 만약 더 이상 읽을 라인이 없으면 break를 수행한다. 여기서 알아두어야 할 것은 f.readline()은 파일의 내용을 한 줄씩 읽어 들인다는 사실이다.
위의 프로그램을 다음 프로그램과 비교해 보자.
while 1:
data = raw_input()
if not data: break
print(data)
위의 예는 사용자의 입력을 받아서 그 내용을 출력하는 예이다. 위의 파일을 읽어서 출력하는 예제와 비교해 보자. 입력을 받는 방식만 틀리다는 것을 금방 알 수 있을 것이다. 두 번째 예는 키보드를 통한 입력방법이고 첫 번째 방법은 파일을 이용한 입력 방법이다.
두 번째 방법
두 번째 방법은 readlines()를 이용하는 방법이다. 다음의 예를 보기로 하자.
# file4.py
f = open("새파일.txt", 'r')
ines = f.readlines()
for line in lines:
print(line)
f.close()
f.readlines()라는 것은 읽기 모드로 열린 파일의 모든 라인을 한꺼번에 읽어서 각각의 줄을 요소로 갖는 리스트로 돌려준다. 따라서 위의 예에서 lines는 [“1 번째 줄입니다.”,“2 번째 줄입니다.”, , , “10 번째 줄입니다.”]라는 리스트가 된다. f.readlines()에서 f.readline()과는 달리 's'가 하나 더 붙어 있음에 주목하도록 하자.
세 번째 방법
세 번째 방법은 read()를 이용하는 방법이다. 다음의 예를 보기로 하자.
# file5.py
f = open("새파일.txt", 'r')
data = f.read()
print(data)
f.close()
f.read()는 파일을 전부 읽은 문자열을 돌려준다. 따라서 위의 예의 data는 파일의 전체내용이다.
파일에 새로운 내용 추가하기
‘w’ 모드로 파일을 연 경우에는 이미 존재하는 파일을 열 경우 그 파일의 내용이 모두 사라지게 된다고 했는데 원래 있던 값을 유지하면서 단지 새로운 값만 추가하기를 원할 수도 있다. 이런 경우에는 파일을 추가 모드('a')로 열면 된다. 다음의 예를 보도록 하자.
# file6.py
f = open("새파일.txt", 'a')
for i in range(11, 20):
data = "%d번째 줄입니다.\n" % i
f.write(data)
f.close()
“새파일.txt"라는 파일을 추가모드('a')로 열은 파일 객체를 만든 다음, 파일 객체의 관련함수인 write를 이용해서 결과값을 파일에 적는다. 여기서 추가 모드로 파일을 열었기 때문에 ”새파일.txt"라는 파일이 원래 가지고 있던 내용 바로 다음에 결과값을 적기 시작한다. “새파일.txt"라는 파일을 읽어서 확인해 보면 원래있던 파일 뒷부분에 새로운 부분이 추가 되었음을 확인 할 수 있을 것이다.
[참고] tell과 seek
파일객체 관련 함수로 ‘tell’과 ‘seek’도 빼놓을 수 없다. ‘tell’은 지금 현재 파일 포인터의 위치를 반환하고, seek은 지정하는 곳으로 포인터의 위치를 변화시킬 수 있는 파일객체 관련 함수이다. 파일 포인터란 파일의 현재 위치를 가리키는 말이다. 대화형 인터프리터를 실행시키고 다음을 따라해 보자.
>>> f = open("test.txt", 'w')
>>> f.write("this is one line\n")
>>> f.write("two line\n")
>>> f.write("three line\n")
>>> f.close()
우선 test.txt라는 파일을 쓰기 모드로 열어서 파일 객체를 생성한후 write함수를 이용하여 총 세 개의 줄을 test.txt파일에 입력하고 파일 객체를 닫는다. test.txt파일은 다음과 같을 것이다.
<test.txt파일 내용>
this is one line
two line
three line
다음의 예를 계속해서 따라해 보자.
>>> f = open("test.txt", 'r')
>>> f.tell()
0
처음에 파일을 읽기 모드로 열었고, 그 파일 포인터 값을 알기 위해서 tell을 호출하였다. 물론 파일의 맨 처음이기 때문에 0을 반환했다.
>>> f.readline()
'this is one line\n'
>>> f.tell()
18
다음에 한 줄을 읽는다. 그 다음의 파일 포인터는 그 줄의 바이트 수만큼 포인터가 증가한다.
따라서 다시 tell을 호출했을 때 18이 된 것이다.
>>> f.readline()
'two line\n'
>>> f.tell()
28
마찬가지로 다시 한 줄을 읽었더니 파일 포인터의 위치는 28이 되었다.
>>> f.seek(0)
>>> f.readline()
'this is one line\n'
>>>
파일 포인터의 값을 변화시키기 위해서 seek를 사용하였다. f.seek(0)는 파일 포인터의 위치를 0으로 하라는 것이다. 따라서 다음에 다시 한 줄을 읽었을 때는 그 파일의 맨 처음 줄을 읽게 되는 것이다.
명령행 입력
이전에 도스를 사용해 본 독자라면 다음과 같은 명령어를 사용해 본적이 있을 것이다.
C:\> type a.txt
위의 type명령어는 뒤에 파일이름을 인수로 받아서 그 내용을 출력해 주는 도스 명령어이다.
도스명령어 [인수1 인수2]
많은 도스 명령어가 위와 같은 방식을 따른다. 즉 명령행(도스창)에서 입력인수를 직접 주어서 프로그램을 실행시키는 방식이다. 이러한 기능을 파이썬 프로그램에도 적용시킬 수가 있다.
파이썬에서는 sys란 모듈을 이용하여 이것을 가능하게 한다. sys라는 모듈을 쓰려면 아래의 예에서 같이 import sys처럼 import라는 명령어를 사용해야 한다. 모듈을 사용하고 만드는 방법에 대해서는 뒤에서 자세히 다룰 것이다.
#sys1.py
import sys
args = sys.argv[1:]
for i in args:
print( i )
위의 프로그램을 C:\Python이란 디렉토리에 저장하고 윈도우즈 도스창을 열고 다음과 같이 입력해 보자.
C:\Python>python sys1.py aaa bbb ccc
다음과 같은 결과 값을 볼 수 있을 것이다.
결과값:
aaa
bbb
ccc
sys모듈의 argv는 명령창에서 입력한 인수들의 리스트를 나타낸다. 즉, argv[0]는 파일 이름인 sys1.py가 되고 argv[1]부터는 뒤에 따라오는 인수들이 차례로 argv의 요소가 된다. 위의 예는 입력받은 인수들을 for문을 이용해 차례대로 하나씩 출력하는 예이다.
위의 예를 이용해서 간단한 스크립트를 하나 만들어 보자.
#sys2.py
import sys
args = sys.argv[1:]
for i in args:
print( i.upper())
문자열 관련함수인 upper()를 이용한 명령행에서 입력된 소문자를 대문자로 바꾸어 주는 간단한 프로그램이다. 도스창에서 다음과 같이 입력해 보자. (주의: sys2.py 파일이 C:\Python이란 디렉토리내에 있어야만 한다.)
C:\Python> python sys2.py life is too short, you need python
결과값:
LIFE IS TOO SHORT, YOU NEED PYTHON