PY | 파일과 예외처리

Stellar·2023년 11월 6일
0

Python

목록 보기
33/36
post-custom-banner

파일

1. 파일의 필요성

메모리는 컴퓨터가 꺼지면 삭제되고 그 파일을 HDD, SSD 등에 저장을 해둬야 한다. 파일안에는 바이트들이 순차적으로 저장되어 있고 맨 끝에는 EOF 마커가 있다.

✔️ 파일 종류

  • 텍스트
  • 이진 파일(binary file) : 이미지, 동영상 등의 파일을 의미

기본 문법

#객체명 = open ('파일 이름.확장자', ''파일 모드', encoding = 'utf - 8')
infile = open('testname.txt', 'r', encoding = 'utf - 8') # 'utf - 8'로 변환해줘야 함.

infile.close() # close()를 꼭 해줘야 함.

✔️ encoding = 'utf - 8', 인코딩은 utf-8파일에서만 사용하기

메모장 기준으로 다른이름으로 저장하기를 하면 인코딩 설정이 뜨는데 이때 utf-8로 저장한 파일에는 infile = open('phones.txt', 'r', encoding = 'utf - 8')와 같이 utf-8을 작성하고 ANSI인 경우 encoding 부분을 지우고 사용한다. infile = open('phones.txt', 'r'')

✔️ 파일 모드

알파벳모드
r읽기 모드
w쓰기 모드
a추가 모드
r+읽기와 쓰기

2. 파일 읽기

한글을 1개당 2byte, 영어는 1개당 1byte
메모장 encode를 ANSI로 해두고 실행해야 제대로 나옴. 다른이름으로 저장 참고.

✔️ read(), 전체 및 정해진 개수만큼 읽어오기

전체 내용 가져오기

infile = open('phones.txt', 'r', encoding = 'utf - 8')
s = infile.read()
print(s)
infile.close()

개수만큼 내용 가져오기

infile = open('phones.txt', 'r', encoding = 'utf - 8')
s = infile.read(10) #개수를 정해서 불러올 수 있다.
print(s)
infile.close()

✔️ readline(), 한 줄만 읽어오기

readline()과 print()는 한 세트로 가져와야 한 줄씩 출력된다.

infile = open('phones.txt', 'r', encoding = 'utf - 8')
s = infile.readline()
print(s)
s = infile.readline()
s = infile.readline()
print(s)
infile.close()
============================ RESTART: C:/Users/GIEC/Desktop/기초문법/1103/파일연습/1103.py ============================
김지수 010-2112-4545

박은찬 010-4985-1384
# 원래 박은찬 위에 홍길동이 있는데 코드 상으로 마지막에 읽은걸 출력하기 때문에 홍길동은 지나치고 박은찬이 출력 됨.

✔️ readline(), 한 줄씩 파일 끝까지 가져오기. while

문장과 문장 사이에 간격이 생김.
김지수 010-2112-4545
...
홍길동 010-1234-5678

infile = open('phones.txt', 'r', encoding = 'utf - 8')
line = infile.readline()
while line != '':
    print(line)
    line = infile.readline()

infile.close()

readline() 예제. while 문장을 세어보자.

f = open('live.txt', 'rt', encoding = 'utf - 8')
text = ''
line = 1
while True :
    row = f.readline()
    if not row : break
    text += str(line) + ' : ' + row
    line += 1

f.close()
print(text)

readline() 예제-1. while 문장을 세어보자 2.

infile = open('proverbs.txt') #저장된 파일 열기
outfile = open('output.txt', 'w') #새로운 파일 생성
text = ''
i = 1
while True :
    row = infile.readline()
    if not row : break
    text += str(i) + ' : ' + row
    i += 1

outfile.write(text) #직접만든 파일에 변수 text 작성.
infile.close()
outfile.close()
print(text)

readline() 예제2. 한 줄씩 파일 끝까지 가져오기. for

문장과 문장 사이에 간격이 없음.
김지수 010-2112-4545
홍길동 010-1234-5678

infile = open('phones.txt', 'r', encoding = 'utf - 8')
for line in infile :
    line = line.rstrip()
    print(line)

infile.close()

✔️ split으로 단어 끊어 읽어오기

infile = open('proverbs.txt', 'r')
for line in infile :
    line = line.rstrip()
    word_list = line.split()
    for word in word_list :
        print(word)

infile.close()

✔️ seek(바이트, 시작위치), 지정된 개수만큼 건너뛰고 읽어오기.

f = open('live.txt', 'rt')
f.seek(12, 0)
text = f.read()
f.close()
print(text)

✔️ tkinter를 사용해 창을 띄워 파일을 가져오자.

from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import asksaveasfilename

readFile = askopenfilename()
if readFile != None :
    infile = open(readFile, 'r')

for line in infile.readlines() :
    line = line.strip()
    print(line)

infile.close()

✔️ csv 파일 읽기

CSV(Comma Separated Values)란 콤마로 구분된 파일을 뜻 함. 스프레드시트, DB 등의 파일
메모에서 확장자명을 .csv로 하면 엑셀 파일로 저장이 된다.

f = open('data.csv', 'r')

for line in f.readlines():
    line = line.strip() #공백 제거
    print(line)
    parts = line.split(',') #콤마로 구분
    for part in parts:
        print('    ', part)

3. 파일 쓰기

✔️ write(), 파일을 생성 후 내용 입력까지

줄바꿈을 별도로 하지 않을 경우 한 줄로 입력된다.

import os

outfile = open('phones2.txt', 'w', encoding = 'utf-8')

outfile.write('신짱구 010-1514-8778\n')
outfile.write('황커피 010-1514-8778\n')
outfile.write('황라떼 010-1514-8778\n')

outfile.close()

파일 쓰기 예제.

f = open('live.txt', 'wt', encoding = 'utf-8')
f.write('''삶이 그대를 속일지라도
슬퍼하거나 노하지 말라!
우울한 날들을 견디면
믿으라. 기쁨의 날이 오리니''')
f.close()

파일 쓰기 예제2. 기존 파일에 내용 추가하기.

f = open('live.txt', 'at')
f.write('\n\n푸쉬킨 형님의 말씀이었습니다.')
f.close()

파일 쓰기 예제3. 문장 별로 번호를 붙여보자.

infile = open('proverbs.txt')
outfile = open('output.txt', 'w')
i = 1
for line in infile:
    outfile.write(str(i) + ': ' + line)
    i += 1

infile.close()
outfile.close()

✔️ 파일 읽기 쓰기 종합예제.

#입력 파일 이름과 출력 파일 이름을 받는다.
infilename = input('입력 파일 이름: ') #sales.txt
outfilename = input('출력 파일 이름: ') #slaesreport.txt

#입력과 출력을 위한 파일을 연다.
infile = open(infilename, 'r', encoding = 'utf-8') 
outfile = open(outfilename, 'w', encoding = 'utf-8') 

#합계와 횟수를 위한 변수를 정의한다.
sum = 0
count = 0

#입력 파일에서 한 줄을 읽어서 합계를 계산한다.
for line in infile :
    dailySale = int(line)
    sum += dailySale
    count += 1

#총매출과 일평균 매출을 출력 파일에 기록한다.
outfile.write('총매출 = ' + str(sum) + '\n')
outfile.write('평균 일매출 = ' + str(sum/count))

infile.close()
outfile.close()

4. 파일을 이용한 메소드

✔️ 파일을 불러와 스페이스와 탭의 개수를 세보자.

def parse_file(path) :
    infile = open(path)
    spaces = 0
    tabs = 0
    for line in infile :
        spaces += line.count(' ')
        tabs += line.count('\t')
    infile.close()

    return spaces, tabs

filename = input('파일 이름을 입력하세요 : ')
spaces, tabs = parse_file(filename)
print('스페이스 수 = {}, 탭의 수 = {}'.format(spaces, tabs))

✔️ 알파벳 개수를 세어보자.

filename = input('파일명을 입력하세요 : ').strip()
infile = open(filename, 'r')

frequs = {}

for line in infile:
    for char in line.strip():
        if char in frequs:
            frequs[char] += 1
        else:
            frequs[char] = 1

print(frequs)
infile.close()

5.임의 접근, 이진 파일

✔️ 이진 파일(Binary file)

이진 파일은 이미지등의 파일을 이진 데이터(010110)로 직접 저장되어 있는 파일이다.
파일은 오픈할 때 rb, wbb는 바이너리 파일을 의미하므로 꼭 적어줘야 함.

바이너리 예제. 이미지 파일 코드로 복사하기.

filename1 = input('원본 파일 이름을 입력하시오: ') #123.png
filename2 = input('복사 파일 이름을 입력하시오: ') #bsh.png

infile = open(filename1, 'rb')
outfile = open(filename2, 'wb')

#입력 파일에서 1024 바이트씩 읽어서 출력 파일에 작성.
while True:
    copy_buffer = infile.read(1024)
    if not copy_buffer:
        break
    outfile.write(copy_buffer)

infile.close()
outfile.close()
print(filename1 + '를 ' + filename2 +'로 복사하였습니다.')

✔️ 임의 접근 파일 tell(), seek()

파일 포인터를 이동시켜

infile = open('test.txt', 'r+') #seek() 함수 사용 시 r+ (읽기 쓰기 가능)를 사용한다.

str = infile.read(10)
print('읽은 문자열 : ', str)

position = infile.tell() #tell(), 현재 위치를 알려 줌.
print('현재 위치 : ', position)

print('계속 읽은 문자열 : ', infile.read(10))

position = infile.seek(0, 0) #seek(), 처음 위치로 이동함.
str = infile.read(10)
print('다시 읽은 문자열 : ', str)
infile.close()

6.메소드

✔️ pickle, 객체 입출력

pickle 모듈의 dump()와 load() 메소드를 사용하면 객체를 쓰고 읽을 수 있다.
피클 데이터는 바이너리 데이터이고 파일 형식을 그대로 저장할 수 있다.

import pickle

myMovie = {'Superman vs Batman ' : 9.8, 'Ironman' : '9.6'}

#딕셔너리를 피클 파일에 저장
pickle.dump(myMovie, open('save.p', 'wb'))

#피클 파일에 딕셔너리를 로딩
myMovie = pickle.load( open( 'save.p', 'rb'))
print(myMovie)

예외처리

2.예외처리

오류가 발생했을 때 사용자에게 무엇으로 인한 오류인지 알려주고 종료할 수 있다.

기본 문법

try :
예외가 발생할 수 있는 문장
except :
예외를 처리하는 문장

✔️ 예외처리 예제. ZeroDivisionError

x, y = 2, 0

try :
    z = x/y
except ZeroDivisionError:
    print('0으로 나누는 예외')

✔️ 예외처리 예제2. ValueError

2-1.

while True :
    try :
        n = input('숫자를 입력하시오 : ')
        n = int(n)
        break
    except ValueError :
        print('정수가 아닙니다. 다시 입력하시오.')
print('정수 입력을 성공했습니다.')

2-2.

def calcsum(n) :
    if n < 0 :
        raise ValueError
    sum = 0
    for i in range(n+1) :
        sum = sum + i
    return sum

try :
    print('~10 = ', calcsum(10))
    print('~-5 = ', calcsum(-5))

except ValueError:
    print('입력 값이 잘못되었습니다.')

2-3. -1을 반환

def calcsum(n) :
    if n < 0 :
        return -1
    sum = 0
    for i in range(n+1) :
        sum = sum + i
    return sum

result = calcsum(10)
if result == -1:
    print('입력값이 잘못되었습니다.')
else :
    print('~10 = ', result)

result = calcsum(-5)
if result == -1:
    print('입력값이 잘못되었습니다.')
else :
    print('~10 = ', result)

None 값을 리턴

dic = {'boy' : '소년', 'school' : '학교', 'book' : '책'}
try :
    print(dic['girl'])
except:
    print('찾는 단어가 없습니다.')

# None 값을 리턴
han = dic.get('girl')
if han == None :
    print('찾는 단어가 없습니다.')
else :
    print(han)

✔️ 예외처리 예제3. IOError

try :
    fname = input('파일 이름을 입력하시오 : ')
    infile = open(fname, 'r')
except IOError :
    print( '파일 ' + fname + '을 발견할 수 없습니다.')

✔️ 예외처리 예제4. else

try :
    fh = open('testfile', 'w')
    fh.write('테스트 데이터를 파일에 씁니다!')
except IOError :
    print( 'Error : 파일을 찾을 수 없거나 데이터를 쓸 수 없습니다.')
else :
    print('파일에 성공적으로 기록했습니다.')
    fh.close()

✔️ 예외처리 예제5. finallry

어떤 상황에서도 finallry가 사용 됨.

try :
    fh = open('testfile', 'w')
    fh.write('테스트 데이터를 파일에 씁니다!')
    #파일 연산을 수행.
except IOError :
    print( 'Error : 파일을 찾을 수 없거나 데이터를 쓸 수 없습니다.')
finally :
    f.close()

✔️ 예외처리 예제6. FileNotFoundError

try :
    f = open('live.txt', 'rt', encoding = 'utf-8')
    text = f.read()
    print(text)
except FileNotFoundError :
    print('파일이 없습니다.')
finally :
    f.close()

✔️ assert, 중간 체크용. 검증이 끝난 후 삭제하는 것이 좋다.

score = 108
assert score <= 100, '점수는 100 이하여야 합니다.'
print(score)
post-custom-banner

0개의 댓글