본문 바로가기
Programming Language/Python

[파이썬] DAY8 파일 입출력 & 예외 처리 복습

by 9루트 2022. 1. 25.

1.  파일 입출력

파일 입출력 복습 

 

파일로 불러올 수 있는 형식 : 텍스트 / 이진 파일

피일의 입출력 보조기억장치인 하드디스크에서 가져오겠다.

 

직접 메모리로 가져오는 것이 아니라 파일에 대한 내용에 대한 경로를 연결해준다.

 

텍스트 파일 입출력 모드 4가지-----------------------------------

r : read

w : write

a : append

r+ : 읽기와 쓰기 모드

파일포인터 : 파일에 접근해주는 경로를 만들어 연결해주는 역할, 일방 통행길(쓰기 모드나 읽기모드 중 한번에 하나만 가능)

 

파일입출력(중심은 메모리 관점에서 생각해야 한다.)

입력: 파일에서 데이터를 메모리로 가지고 들어오는 것 

출력: 메모리에서 데이터를 파일로 가지고 나가는 것

 

 

한 줄로 가지고 온 다음에 개행문자를 날려서 데이터를 받는다.

개행 문자 line = line.rstrip ( )

 

 

 

이진 파일 입출력 모드 4가지----------------------------------------------------------------

rb : read

wb : write

ab : append

rb+ : 읽기와 쓰기 모드

 

 

시작부분에서 끝부분까지 지정해서 한 줄로 읽어온다.

open( 파일이름 , 파일 포인터) - close() 

는 이진 파일 입출력에도 마찬가지로 들어간다.

더 이상 쓰지 않겠다면 파일 포인터도 객체이므로 메모리 낭비를 줄이기 위해 close() 를 써야 한다.

파일 포인터, 파일이름, 파일포인터모드, 인코딩 코드 형식

각 나라마다 유니코드의 넘버링이 다르다. 데이터들을 인코딩 디코딩 기반으로 숫자로 저장된다.

encoding = 'UTF-8' : 코드 형식을 맞춰준다. 

파일 포인터는 주소이다. : 첫번째 데이터가 작성된 위치

텍스트 파일에서는 파일 포인터가 개행문자로 끝을 인식하여 데이터 갯수를 가지고 온다.

 

 

객체 입출력(이진 파일 형태로 입출력)

pickle 의 원리

표 데이터라는 객체를 저장하려면 이진 파일로 일렬로 (직렬화) 데이터를 만들어 저장한다.

다시 원래 모양으로 거꾸로 뭉쳐놓으면 (역직렬화) 

 

pickle : 객체 자체를 고유하게 읽고 쓸 수 있게 한다. 외부 모듈로 import로 가져와야 한다.

 

파일에 객체 저장한다.

 

내부 모듈(내장 함수): 상위 단에 클래스에 있는 메소드, 책상(소스 코드 안)
외부 모듈(외부 함수): 사물함에 있으므로 코드 밖에 있지만 코드 안으로 가지고 올 수 있다. 
코랩은 사물함에 다 준비가 되어있다, 파이썬은 패키지라는 모듈 모음을 수동적으로 설치해주어야 한다.

중간에 i_f.close()를 꼭 넣어야 한다.: 동시에 읽고 쓰고 불가하므로 하나를 닫아주어야 한다.

중간에 i_f.close()를 꼭 넣어야 한다.: 동시에 읽고 쓰고 불가하므로 하나를 닫아주어야 한다.

 

https://www.data.go.kr/

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

에서 csv 파일 같은 데이터 시트를 가져올 수 있다.

하지만 머리가 터지므로

인공지능 할 때는 패키지로 가져온다.

 

 


2. 예외 처리

 

에러가 난 코드가 있어도 그 부분만 제외하고 코드가 끝까지 작동되도록 한다.

미리 우회할 경로를 만들어놓는다. (경험론적 기법)

 

cf) 그 자리에 해당 파일이 있는 확인해주는 메소드가 있다.

 

"wb" : 기존 파일에 데이터가 있으면 데이터를 삭제하고 다시 처음부터 쓴다.

→ "ab"를 사용한다.

 

입출력 예외 IOError : 텍스트 / 이진 파일 입출력 모두 가능하다.

save1.p 파일이 없으므로 예외가 동작한다.
save.p 파일이 있으므로 예외가 동작하지 않는다.

 

텍스트 파일에서도 IOError를 쓸 수 있다.

 

 

else블럭 : 어떠한 예외 처리가 동작하지 않았을 때 동작한다.

 

 

이름을 만들어낸다 = 객체를 참조한다. 메모리 공간에 동적할당하여 객체를 만든다.

-> 그 누구도 참조하지 않는 객체 = garbage가비지

 

finally 와 else 의 차이

finally 와 else는 자원을 정리해주는 역할을 한다. 따라서 자원 정리 유무에 따라 finally 영역과 메인 영역은 다르다.

else : 예외 처리에서 else는 자원의 정리 목적은 맞지만 예외가 발생하지 않았을 때만 동작

finally : 예외 처리에서 남는 자원을 정리한다. 자원 정리라는 구분을 위해서 finally 블락을 넣어주는 것임(정리가 목적), 필수는 아님

 

주의

except 단에서 

상위단(부모)의 예외 클래스는 

여러 조건의 예외 처리를 할 때 반드시 하위로 두어야 한다. 

왜냐하면 위 상위단 예외 클래스가 경우를 다 가져가므로 하위단 자식 예외 클래스는 의미가 없어지므로 오류가 발생한다.

 

 

try는 정확한 부분만 설정하는 것이 좋다.

 

 


3. 예외 발생하기

또는 예외 전달하기 구문이라고 한다. (try - except 블럭이랑 다른 영역이기 때문)

try - except 구문은 예외 처리하기 구문이다.

 

예외는 모두 클래스다

예외가 발생하면 객체가 만들어진다.

상속을 하여 오버라이딩하면 나만의 예외 처리가 가능하다.

원하는 예외를 설정하여 처리가 가능하다.

대괄적인 구조, 이후 예외 이름의 클래스 추가되어야 한다.
예외 객체를 넣어줘야 한다. e = 예외 메세지가 담겨있다.

 

 

# 상속으로 나만의 예외 클래스 만들 때
class A(Exception):
  def __init__(self, 예외입력):
    super().__init__(예외입력) # ( )에 직접적으로 string 넣으면 된다.

def f():
    raise Exception("과도한 출금입니다.")

def out_f():
  try:
    f()
  except Exception as e:
    #Exception("내부 예외 발생")
    raise 


# 은행 마이너스 통장이 되면 안된다.
try:
  x = -1
  if x < 0:
    out_f() # 과도한 출금입니다.
  elif x == 0:
    raise A("잔액이 없습니다.") # A의 객체가 만들어진다.
except A as errorMessage:
  print(A)
  print(errorMessage)
except Exception as errorMessage:
  print(errorMessage)

 

 

raise: 발생한 에러를 전달하는 역할을 한다, 또한 영역 밖으로 나온다. 

raise

 

에러 발생 -> "과도한 출금입니다." 출력

Exception("과도한 출금입니다.")

 

errorMessage: A라는 상속된 예외 자식 클래스의 텍스트 메세지를 의미한다. 이름 마음대로 정할 수 있다.

except A as errorMessage:

 

 

 

 

x < 0 이면 

과도한 출금입니다.

출력

 

 

x = 0 이면

<class '__main__.A'>
잔액이 없습니다.

출력

print(A)는 A 클래스의 영역이 나오고

print(errorMessage)는 A가 가지고 있는 에러 메세지가 나온다.

 

except A as errorMessage:
  print(errorMessage)

except Exception as a:
  print(a)

잔액이 없습니다. 출력

에서

except Exception as a:
  print(a)

만 해도 똑같이

잔액이 없습니다. 출력된다.

 

이는 

# 상속으로 나만의 예외 클래스 만들 때
class A(Exception):
  def __init__(self, 예외입력):
    super().__init__(예외입력) # ( )에 직접적으로 string 넣으면 된다.

여기서 하위 클래스(A)의 생성자 초기값을 동시에 상위 클래스(Exception)의 생성자에도 넣었기 때문이다.