[파이썬기초] 07. 파일과 예외처리

일리삼·2022년 6월 4일

파이썬

목록 보기
7/10

1. 파일 처리

  • 컴퓨터의 저장 장치 내에 데이터를 저장하기 위해 사용하는 논리적인 단위
  • 프로그램에서 만든 데이터를 영구히 저장하고자 한다면 HDD에 파일 형태로 저장

1.1 파일 사용 절차

1.1.1 파일 열고 닫기

(파일 객체) = open('파일경로', '읽기모드')
  • 파일 경로에는 파일명이나 실제 파일의 경로(path)를 입력
  • 읽기모드에는 다음과 같은 것을 지정할 수 있음
    • w: write 모드 (새로 쓰기 모드)
    • a: append 모드 (뒤에 이어서 쓰기 모드)
    • r: read 모드 (읽기 모드)
    • r+: 읽기와 쓰기 모드이며, 모드를 변경하려면 seek()가 호출되어야 함
    • 모드 뒤에 't' (to texe mode), 혹은 'b' (to bin mode)를 붙일 수도 있음
      • ex) open('myfile', 'wb') # bin + write mode로 파일을 읽겠다
(파일 객체).close()
  • 이 함수를 사용하면 파일을 닫을 수 있음

1.1.2 파일 쓰기

# 방법1) write()
(파일 객체).write('내용')

# 방법2) print()
print('내용', file=(파일객체))
  • write()메소드를 사용하는 경우에는 자동 개행이 불가하므로 맨 마지막에 개행 문자를 넣어줘야함.
  • 내장함수 print()의 경우, 출력 파일의 기본값이 모니터이므로 이를 작성하고자 하는 파일로 변경해주면 해당 파일에 내용이 써짐

1.1.3 파일 읽기

1.1.3.1 readline()

  • 현재 라인의 끝에 도달할 때까지 읽어 그 결과를 반환
  • 줄 바꿈 문자를 포함함에 유의
  • 파일이 끝나면 빈 문자열을 반환
def readline_test1():
	my_file = open('myfile.txt', 'r')
    line = my_file.readline().rstrip()
    while line:
        print(line)
        line = my_file.readline().rstrip() 
    
    my_file.close()
    

1.1.3.2 for문을 사용

  • readline()과 유사하지만 다시 읽으려면 파일을 재오픈
def read_using_for():
	my_file = open('myfile.txt', 'r')
    for line in my_file: # for line in list(my_file)도 가능
    	print(line.rstrip()
        
    my_file.close()

1.1.3.3 readlines()

  • 각 라인이 저장된 리스트를 반환
def readlines_test():
	my_file = open('myfile.txt', 'r')
    lst = my_file.readlines()
    
    for line in lst:
    	print(line.rstrip())

1.1.3.4 read()

  • 파일 전체를 하나의 문자열로 읽어옴
  • 원하는 개수만큼 문자 읽기 가능
def read_test():
	my_file = open('myfile.txt', 'r')
    s = my_file.read()
    
    for line in f:
    	print(line.rstrip())

1.1.4 with() 키워드 사용

  • 프로그램이 길어지면 open()함수와 close()함수 사이에 많은 코드가 들어가는데, 이때 파일을 열고 닫지 않는 실수가 발생할 수 있음
  • 이러한 실수를 방지하기 위해 with()키워드 사용
with open('파일명', '모드') as (파일 객체):
	문장
  • 자동으로 블록을 빠져나오면 파일이 닫힘

1.2 CSV 파일 처리

  • CSV는 Comma Separated Values의 줄임말로 쉼표로 구분된 값을 의미
이름, 키, 몸무게
김철수, 176, 62
이영희, 155, 49
  • 해당 파일을 처리할 때는 보통 한 줄씩 읽어가며 처리함

1.2.1 CVS 모듈X

# weather.csv 파일은 20년 동안 매일 모 강의실의 기온이 측정된 파일 자료
def without_csvModule():
    with open("weather.csv", "rt") as f: 
        
        temp = 100
        f.readline()
        line = f.readline()
        
        while line:
            line = line.split(',')
            if temp > float(line[3]):
                temp = float(line[3])
            
            line = f.readline()
            
        print('가장 추운 날의 기온', temp)
  • 위 처럼 readline()을 이용해 한 줄씩 읽어가며 파일 처리

1.2.2 CVS 모듈 사용

def q4_w_csv():
    import csv
    with open('weather.csv', 'rt') as f:
        data = csv.reader(f) # readline()을 이용하는 것과 동일
        next(data) # 다음 번째 line을 읽어옴
        
        temp = 100
        
        for line in data:
            if temp > float(line[3]):
                temp = float(line[3])
            
            
        print('가장 추운 날의 기온', temp)

1.3 binary file

def bin_write():
    # 바이너리 파일에 0부터 255까지 값 작성
        # read(바이트수) // write(바이트리스트)
    with open('test.bin', 'wb') as f:
        lst = bytes(list(range(256)))
        f.write(lst)
  • 이진 파일에서 데이터를 읽으려면 open()함수의 모드를 'rb'로 열어야함
  • 입력 파일에서 n byte를 읽으려면 read(n)과 같이 사용
  • 이진 파일에 바이트들을 저장하기 위해서는 write(bytes_array[])형태로 들어감

1.4 이미지 파일 복사

def cpy_img():
    # 원본 열기 -> 닫기
    # 복사본 열기 -> 닫기
    # 원본 내용이 있을 동안 원본에서 1024바이트 읽어와서 그대로 복사본에 쓰기
    
    with open ('pic.jpeg', 'rb') as org: # b 빼먹으면 아무것도 안보임
        with open('pic_cpy.jpeg', 'wb') as cpy:
            buf = org.read(1024)
            while buf:
                cpy.write(buf)
                buf = org.read(1024)

2. 예외처리

2.1 오류의 종류

2.1.1 구문 오류(syntax error)

  • 괄호의 개수, 들여쓰기 문제 등으로 프로그램이 실행되기도 전에 발생하는 오류
  • 구문 오류는 해결하지 않으면 프로그램 자체가 실행되지 않으므로 코드를 제대로 수정해야함
SyntaxError: EOL while scanning string literal
  • 구문 오류 발생 시, SyntaxError이라는 단어와 함께 출력됨

2.1.2 예외(exception)

  • 런타임 오류(runtime error)라고도 불림
  • 프로그램이 실행된 다음, 실행중에 발생하는 오류로 제대로 해당 오류를 수정하여야 함

2.2 예외 처리(Exception Handling)

예외 발생 코드

number_input_a = int(input('정수 입력 >'))

print("원의 반지름:", number_input_a)
print("원의 둘레:", 2 * 3.14 * number_input_a)
print("원의 넓이:", 3.14 * number_input_a**2)

사용자가 정수를 입력하지 않았을 때 발생하는 예외

정수입력 > 7센티미터

Traceback (most recent call last):
	File "test.py", line 2, in <module>
    	number_input_a = int(input('정수 입력 > '))
ValueError: invalid literal for int() with base 10: '7센티미터'

2.2.1 조건문 사용

  • '정수를 입력하지 않았을 때'를 조건으로 구분해서 해당 상황일 때 다른 처리를 하는 방법
  • 하지만 예외가 발생할 상황을 모두 예측하고 조건문으로 처리하는 것은 매우 힘들고, 프로그래밍 언어의 구조적인 문제로 인해 조건문만으로 예외를 처리할 수 없는 경우도 있음
user_input_a = input('정수 입력 > ')

if user_input_a.isdigit():
  number_input_a = int(user_input_a)

  print("원의 반지름:", number_input_a)
  print("원의 둘레:", 2 * 3.14 * number_input_a)
  print("원의 넓이:", 3.14 * number_input_a**2)
  
else:
	print("정수를 입력하지 않았습니다.")

2.2.2 try구문 사용

기본 형태

try:
	예외가 발생할 가능성이 있는 코드
    
except: # 오류 입력 안할 시 전체 오류에 대해 탐지
	예외가 발생했을 때 실행할 코드

예제

try:
	number_input_a = int(input('정수 입력 >'))
    
    print("원의 반지름:", number_input_a)
    print("원의 둘레:", 2 * 3.14 * number_input_a)
    print("원의 넓이:", 3.14 * number_input_a**2)

except:
	print("에러 발생!")

2.2.3 try-except-finally 구문의 조합

  • 예외 처리 구문은 다음과 같은 규칙을 지켜야함
    • try 구문은 단독으로 사용할 수 없으며, 반드시 except 구문 또는 finally 구문과 함꼐 사용해야함
    • else 구문은 반드시 except 구문 뒤에 사용해야함
  • 이를 조합해보면 다음과 같음
    • try + except
    • try + except + else
    • try + except + finally
    • try + except + else + finally
    • try + finally
      +) finally 키워드는 어떤 조건에 무조건 사용해야 하는 게 아니라 finally 키워드를 사용하면 코드가 깔끔해질 것 같다고 생각되는 경우에 사용한다는 것을 기억하자

2.2.4 예외 고급

  • 예외가 발생하면 예외 정보가 생기는데 이를 예외 객체(Exception object)라고 함
  • 아래와 같이 예외 객체를 사용할 수 있음
try:
	예외가 발생할 가능성이 있는 코드
    
except (예외 객체) as (예외 객체를 활용할 변수 이름): # 오류 입력 안할 시 전체 오류에 대해 탐지
	예외가 발생했을 때 실행할 코드
  • 예외 객체가 여러개가 나올 경우, except를 반복적으로 사용해 각각의 예외 객체가 발생함에 따라 원하는 코드를 실행할 수 있도록 할 수 있음
  • 특정 예외 객체 외에 나머지 예외가 발생할 경우, if-elif-else구문처럼 마지막에는 모든 예외의 부모라고 할 수 있는 Exception을 넣어 프로그램이 죽지 않도록 함
list_number = [52, 273, 32, 72, 100]

try:
	numper_input = int(input("정수 입력 > "))
    
    print(f'{number_input}번째 요소: {list_number[number_input]}')

except ValueError as exception:
	print("정수를 입력해주세요!")
    print(type(exception), exception)
    
except IndexError as exception:
	print("리스트의 인덱스를 벗어났어요!")
    print(type(exception), exception)

except Exception as exception:
	print("미리 파악하지 못한 예외가 발생했습니다.")
    print(type(exception), exception)

2.2.5 raise 구문

  • 프로그램을 개발하는 동안, 아직 구현하지 않은 부분에 대해 강제로 예외 발생 시킬 때 사용
  • 미구현 부분에 대해 일부러 예외를 발생시켜, 구현되지 않은 부분을 잊지 않도록 만들어줄 때 사용
raise (예외 객체)
  • raise 뒤에 예외 이름을 입력해주면 됨
number = input("정수 입력 > ")
number = int(number)

if number > 0:
	raise NoyImplementedError
 
else:
	raise NotImplementedError
profile
코린이의 취준 자취 기록장

0개의 댓글