<3-1> 파일 입출력
동영상 강의 : http://pythonkim.tistory.com/notice/77
# Day_03_01_file.py
- 파일에는 두가지 종류의 파일이 있다. 우리가 읽을 수 있는 파일(텍스트 파일)과 읽을 수 없는 파일(바이너리 피알)..!!
- 우선 Data 폴더를 만들고 텍스트 파일 하나를 만들자.
김인육, 사랑의 물리학 질량의 크기는 부피와 비례하지 않는다 제비꽃같이 조그마한 그 계집애가 꽃잎같이 하늘거리는 그 계집애가 지구보다 더 큰 질량으로 나를 끌어당긴다. 순간, 나는 뉴턴의 사과처럼 사정없이 그녀에게로 굴러 떨어졌다 쿵 소리를 내며, 쿵쿵 소리를 내며 심장이 하늘에서 땅까지 아찔한 진자운동을 계속하였다 첫사랑이었다. |
>> 위의 시를 poem.txt 파일에 복붙하쟈.
- open() , close()
1 2 3 4 5 6 7 8 | def read_1(filename): f = open(filename, 'r') f.close() filename = 'Data/poem.txt' read_1(filename) | cs |
>> 7 : 경로설정을 잘 해줘야한다. 현재 디렉토리에 있는 Data 폴더에 있는 poem.txt 라는 파일.
>> 프로젝트 폴더가 현재 디렉토리라고 여겨진다.
>> 2 : open() 에서의 옵션 'r' >> 파일을 읽겠다는 뜻.
>> 4 : open() 을 하고 볼일을 다 봤으면 항상 close() 를 해줘야한다.
- 경로에는 절대경로와 상대결로가 있다.
>> 절대경로 : 경로의 풀네임
>> 상대경로 : 현재 경로 기준으로 판단. // . 은 현재 디렉토리, // .. 은 상위 디렉토리
>> 일반적으로 상대경로를 많이 사용한다고 한다.
- 경로를 잘 설정했는데도 에러가 발생했다면 인코딩 문제를 의심해볼 수 있다.
1 | f = open(filename, 'r', encoding='utf-8') | cs |
>> 세번째 옵션으로 인코딩 옵션을 설정한다.
>> 현재 전 세계적으로 텍스트파일에 대한 표준은 utf-8 이라고 한다.
>> html 에서 기본적으로 이것을 사용한다고 한다.
- readlines()
1 2 3 4 5 6 7 8 9 10 11 | def read_1(filename): f = open(filename, 'r', encoding='utf-8') lines = f.readlines() print(lines) f.close() filename = 'Data/poem.txt' read_1(filename) | cs |
>> 4, 5 라인 추가. // readline 과 혼동하지 말자.
>> 실행결과
['김인육, 사랑의 물리학\n', '\n', '질량의 크기는 부피와 비례하지 않는다\n', '\n', '제비꽃같이 조그마한 그 계집애가\n', '꽃잎같이 하늘거리는 그 계집애가\n', '지구보다 더 큰 질량으로 나를 끌어당긴다.\n', '순간, 나는\n', '뉴턴의 사과처럼\n', '사정없이 그녀에게로 굴러 떨어졌다\n', '쿵 소리를 내며, 쿵쿵 소리를 내며\n', '\n', '심장이\n', '하늘에서 땅까지 아찔한 진자운동을 계속하였다\n', '첫사랑이었다.']
1 2 3 4 5 6 7 8 9 10 11 12 13 | def read_1(filename): f = open(filename, 'r', encoding='utf-8') lines = f.readlines() for line in lines: print(line) f.close() filename = 'Data/poem.txt' read_1(filename) | cs |
>> 6, 7 라인의 변경
>> 실행결과
김인육, 사랑의 물리학 질량의 크기는 부피와 비례하지 않는다 제비꽃같이 조그마한 그 계집애가 꽃잎같이 하늘거리는 그 계집애가 지구보다 더 큰 질량으로 나를 끌어당긴다. 순간, 나는 뉴턴의 사과처럼 사정없이 그녀에게로 굴러 떨어졌다 쿵 소리를 내며, 쿵쿵 소리를 내며 심장이 하늘에서 땅까지 아찔한 진자운동을 계속하였다 첫사랑이었다. |
>> 줄바꿈이 심하다. 기본적으로 문자열 내부에 개행을 포함하며, print() 또한 개행을 포함하기 때문이다.
- 7 라인의 print() 에서 end='' 옵션을 추가해보쟈
1 2 3 4 5 6 7 8 9 10 11 12 13 | def read_1(filename): f = open(filename, 'r', encoding='utf-8') lines = f.readlines() for line in lines: print(line, end='') f.close() filename = 'Data/poem.txt' read_1(filename) | cs |
>> 실행결과
김인육, 사랑의 물리학 질량의 크기는 부피와 비례하지 않는다 제비꽃같이 조그마한 그 계집애가 꽃잎같이 하늘거리는 그 계집애가 지구보다 더 큰 질량으로 나를 끌어당긴다. 순간, 나는 뉴턴의 사과처럼 사정없이 그녀에게로 굴러 떨어졌다 쿵 소리를 내며, 쿵쿵 소리를 내며 심장이 하늘에서 땅까지 아찔한 진자운동을 계속하였다 첫사랑이었다. |
>> 하지만 파일을 읽어온 목적이 화면에 출력하는 것은 아니므로, 위와 같은 행위는 바람직하지 않다고 하신다.
>> 출력은 눈으로 확인용일 뿐, 중요하진 않다.
- strip() 사용하기
>> 개행문자가 필요한지 아닌지는 상황에 따라 다를 것이다.
>> 여기서는 필요 없어보인다. 그래서 strip() 을 사용
>> strip() : 문자열 양 끝에 있는 공백을 제거
1 2 3 4 5 6 7 8 9 10 11 12 13 | def read_1(filename): f = open(filename, 'r', encoding='utf-8') lines = f.readlines() for line in lines: print(line.strip()) f.close() filename = 'Data/poem.txt' read_1(filename) | cs |
>> 7 라인과 같이 사용한다.
- strip() 사용법
1 2 3 4 5 | temp = '\t\t\n\n apple koong \n\n\t\t' print('[{}]'.format(temp)) temp = temp.strip() print('[{}]'.format(temp)) | cs |
>> 2 의 실행결과
[
apple koong
]
>> 5 의 실행결과
[apple koong]
>> 문자열 양 끝의 모든 공백들이 제거되었다.
- 파일읽기 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def read_2(filename): f = open(filename, 'r', encoding='utf-8') while True: line = f.readline() # if len(line) == 0: break; # EOF if not line: break; print(line.strip()) f.close() filename = 'Data/poem.txt' read_2(filename) | cs |
>> 5 : readline() 함수는 한줄씩 읽어온다.
>> 6 : EOF 를 만나면 line 의 길이는 0이 된다. 하지만 7 라인과 같은 코딩을 선호한다고 한다.
>> 7 : Python 에서는 비어있는 것에 대해 false 로 판단한다.
- 파일읽기 3
1 2 3 4 5 6 7 8 9 10 11 | def read_3(filename): f = open(filename, 'r', encoding='utf-8') for line in f: print(line.strip()) f.close() filename = 'Data/poem.txt' read_3(filename) | cs |
>> 4 : for in 문에서 in 다음에는 이터러블한 것이라면 올 수 있다. 이처럼 파일도 올 수 있다.
>> EOF 를 만나면 알아서 끝난다.
>> 가장 심플한 코드.
- 파일읽기 4 : with 구문 사용
1 2 3 4 5 6 7 8 9 10 11 | def read_4(filename): with open(filename, 'r', encoding='utf-8') as f: for line in f: print(line.strip()) # f.close() filename = 'Data/poem.txt' read_4(filename) | cs |
>> 2 : with 구문 사용, as f: f 라는 별칭까지 준다.
>> 7 : close() 가 필요가 없다. with 구문의 장점(자동으로 호출이 된다.)
- 파일읽기 5
- 일반적으로 파일을 다루는 코드 (리스트에 넣어서 처리)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 일반적으로 파일을 다루는 코드. # 리스트에 넣어서 처리 def read_5(filename): lines = [] with open(filename, 'r', encoding='utf-8') as f: for line in f: # print(line.strip()) lines.append(line.strip()) return lines filename = 'Data/poem.txt' lines = read_5(filename) | cs |
>>
- readlines() 가 존재하는 이유.
1 2 3 4 5 6 7 8 9 10 11 12 | def read_readlines(filename): f = open(filename, 'r', encoding='utf-8') lines = f.readlines() f.close() return ''.join(lines) filename = 'Data/poem.txt' text_all = read_readlines(filename) print(text_all) | cs |
>> join() 을 호출하기 위해 존재한다고 한다.
>> read_readlines() 가 리턴한 데이터의 타입은 문자열..!!
>> join() 의 역할은 리스트 안에 들어있는 문자열들을 한번에 결합
>> 하나의 변수로 파일의 내용을 다루고자 할 때 readlines() 를 사용한다.
>> 실행결과
김인육, 사랑의 물리학 질량의 크기는 부피와 비례하지 않는다 제비꽃같이 조그마한 그 계집애가 꽃잎같이 하늘거리는 그 계집애가 지구보다 더 큰 질량으로 나를 끌어당긴다. 순간, 나는 뉴턴의 사과처럼 사정없이 그녀에게로 굴러 떨어졌다 쿵 소리를 내며, 쿵쿵 소리를 내며 심장이 하늘에서 땅까지 아찔한 진자운동을 계속하였다 첫사랑이었다. |
cf)
1 | return '***'.join(lines) | cs |
>> 실행결과
김인육, 사랑의 물리학 *** ***질량의 크기는 부피와 비례하지 않는다 *** ***제비꽃같이 조그마한 그 계집애가 ***꽃잎같이 하늘거리는 그 계집애가 ***지구보다 더 큰 질량으로 나를 끌어당긴다. ***순간, 나는 ***뉴턴의 사과처럼 ***사정없이 그녀에게로 굴러 떨어졌다 ***쿵 소리를 내며, 쿵쿵 소리를 내며 *** ***심장이 ***하늘에서 땅까지 아찔한 진자운동을 계속하였다 ***첫사랑이었다. |
- split() 과 join()
1 2 3 4 5 6 | a = 'AA,BB,CC' b = a.split(',') print(b) # ['AA', 'BB', 'CC'] c = ''.join(b) print(c) # AABBCC | cs |
>> 3, 6 의 실행결과는 주석으로 확인.
>> spit() 의 결과는 리스트
- 파일 쓰기
1 2 3 4 5 6 7 8 | def write(): f = open('Data/write.txt', 'w', encoding='utf-8') f.write('Hello ') f.write('Python') f.close() write() | cs |
>> Data 폴더에 write.txt 파일이 생성되고, 'Hello Python' 문자열이 저장되어 있다.
- command 키 누른 상태로 마우스를 open() 위에 가져다 놓기 (win 에서는 ctrl)
>> open() 에 대한 설명을 볼 수 있다.
- 기상청 날씨정보를 파싱 후 파일에 저장
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import requests import re url = 'http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108' recvd = requests.get(url) locations = re.findall(r'<location wl_ver="3">.+?</location>', recvd.text, re.DOTALL) f = open('Data/kma.csv', 'w', encoding='utf-8') def findData(): for loc in locations: prov = re.findall(r'<province>(.+)</province>', loc) city = re.findall(r'<city>(.+)</city>', loc) data = re.findall(r'<data>(.+)</data>', loc, re.DOTALL) for datum in data: mode = re.findall(r'<mode>(.+?)</mode>', datum) tmEf = re.findall(r'<tmEf>(.+?)</tmEf>', datum) wf = re.findall(r'<wf>(.+?)</wf>', datum) tmn = re.findall(r'<tmn>(.+?)</tmn>', datum) tmx = re.findall(r'<tmx>(.+?)</tmx>', datum) reli = re.findall(r'<reliability>(.+?)</reliability>', datum) row = '{},{},{},{},{},{},{},{}'.format(prov[0], city[0], mode[0], tmEf[0], wf[0], tmn[0], tmx[0], reli[0]) print(row) f.write(row) f.write('\n') # 개행문자는 자동으로 처리되지 않으므로. findData() f.close() | cs |
'Language > Python' 카테고리의 다른 글
<3-3> JSON (0) | 2018.03.05 |
---|---|
<3-2> Set 과 Dictionary (0) | 2018.03.02 |
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가 (0) | 2018.02.22 |
<2-2> 리스트, 튜플 (0) | 2018.02.15 |
<2-1> 제어문과 반복문의 연결고리 (0) | 2018.02.06 |