File,Exception,Log Handling

File & Exception & Log Handling


Exception

예상 가능한 예외

  • 발생 여부를 사전에 인지할 수 있는 예외
  • 사용자의 잘못된 입력, 파일 호출 시 파일 없음
  • 개발자가 반드시 명시적으로 정의 해야함

예상 불가능한 예외

  • 인터프리터 과정에서 발생하는 예외, 개발자 실수
  • 리스트의 범위를 넘어가는 값 호출, 정수 0으로 나눔
  • 수행 불가시 인터프리터가 자동 호출

Exception Handling

image.png

In [1]:
for i in range(10):
    try:
        print(10 / i)
    except ZeroDivisionError:
        print("Not divided by 0")
Not divided by 0
10.0
5.0
3.3333333333333335
2.5
2.0
1.6666666666666667
1.4285714285714286
1.25
1.1111111111111112
  • 0으로 숫자를 나눌때 예외처리 하기
In [2]:
a=[1,2,3,4,5]
for i in range(10):
    try:
        print(10 / i)
        print(a[i])
        print(v)
    except ZeroDivisionError:
        print("Not divided by 0")
    except IndexError as e:
        print(e)
    except Exception as e:        # 나머지 예외를 잡는다.
        print(e)
Not divided by 0
10.0
2
name 'v' is not defined
5.0
3
name 'v' is not defined
3.3333333333333335
4
name 'v' is not defined
2.5
5
name 'v' is not defined
2.0
list index out of range
1.6666666666666667
list index out of range
1.4285714285714286
list index out of range
1.25
list index out of range
1.1111111111111112
list index out of range
  • 여기서 Exception으로 전체 예외를 잡게 되면 어디서 에러가 났는지 모른다.
  • 전체를 잡는 Exception으로 그렇게 좋지 않는 코드이다.

Exception의 종류

image.png

else 구문

image.png

In [3]:
for i in range(10):
    try:
        result= 10 / i
    except ZeroDivisionError:
        print("Not divided by 0")
    else:
        print(10 / i)
Not divided by 0
10.0
5.0
3.3333333333333335
2.5
2.0
1.6666666666666667
1.4285714285714286
1.25
1.1111111111111112

finally 구문

image.png

In [4]:
try:
    for i in range(1,10):
        result= 10 / i
        print(result)
except ZeroDivisionError:
    print("Not divided by 0")
finally:
    print('종료되었습니다.')
10.0
5.0
3.3333333333333335
2.5
2.0
1.6666666666666667
1.4285714285714286
1.25
1.1111111111111112
종료되었습니다.

raise 구문

image.png

In [5]:
while True:
    value= input("변환할 정수 값을 입력해주세요")
    for digit in value:
        if digit not in "0123456789":
            raise ValueError("숫자값을 입력하지 않으셨습니다")
        print("정수값으로 변환된 숫자-", int(value))
변환할 정수 값을 입력해주세요6
정수값으로 변환된 숫자- 6
변환할 정수 값을 입력해주세요number
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-815e7178f4eb> in <module>
      3     for digit in value:
      4         if digit not in "0123456789":
----> 5             raise ValueError("숫자값을 입력하지 않으셨습니다")
      6         print("정수값으로 변환된 숫자-", int(value))

ValueError: 숫자값을 입력하지 않으셨습니다

assert 구문

image.png

In [6]:
def get_binary_nmubmer(decimal_number):
    assert isinstance(decimal_number, int)
    return bin(decimal_number)
print(get_binary_nmubmer(10))
print(get_binary_nmubmer('1'))
0b1010
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-6-df3639c8311e> in <module>
      3     return bin(decimal_number)
      4 print(get_binary_nmubmer(10))
----> 5 print(get_binary_nmubmer('1'))

<ipython-input-6-df3639c8311e> in get_binary_nmubmer(decimal_number)
      1 def get_binary_nmubmer(decimal_number):
----> 2     assert isinstance(decimal_number, int)
      3     return bin(decimal_number)
      4 print(get_binary_nmubmer(10))
      5 print(get_binary_nmubmer('1'))

AssertionError: 
  • assert구문 다음에는 조건문이 들어오게 된다.
  • 이때 True이면 넘어가고, False이면 에러가 발생하게 된다.


File Handling

파일의 종류

image.png

Python File I/O

image.png

1) File Read

In [10]:
f= open("./data/i_have_a_dream.txt","r")
contents= f.read()
print(contents)
f.close()
I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.

Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity.

But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition.
  • read(): txt파일 안에 있는 내용을 문자열로 반환
In [11]:
with open("./data/i_have_a_dream.txt","r") as my_file:
    contents=my_file.read()
    print(type(contents),contents)
<class 'str'> I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.

Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity.

But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition.
  • with 구문과 함께 사용하기
  • with 구문까지는 계속 파일이 열린 상태이고 구문이 끝나면 알아서 close()가 실행된다.
In [12]:
with open("./data/i_have_a_dream.txt","r") as my_file:
    content_list=my_file.readlines()   # 파일 전체를 list로 반환
    print(type(content_list))   # Type 확인
    print(content_list)         # 리스트 값 출력
<class 'list'>
['I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.\n', '\n', 'Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity.\n', '\n', "But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition."]
  • readlines()는 \n(개행)을 기준으로 list로 나눈다.
In [13]:
with open("./data/i_have_a_dream.txt","r") as my_file:
    i=0
    while True:
        line=my_file.readline()
        if not line:
            break
        print(str(i) + ' === ' + line.replace('\n','')) #한줄씩 값 출력
        i+=1
0 === I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.
1 === 
2 === Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity.
3 === 
4 === But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition.
  • 실행 시 마다 한 줄 씩 읽어 오기
In [14]:
with open("./data/i_have_a_dream.txt", "r") as my_file:
    contents= my_file.read()
    word_list= contents.split(" ") # 빈칸 기준으로 단어를 분리 리스트
    line_list= contents.split("\n") # 한줄씩 분리하여 리스트

print("TotalNumberof Characters:", len(contents))
print("TotalNumberof Words:", len(word_list))
print("TotalNumberof Lines :", len(line_list))
TotalNumberof Characters: 990
TotalNumberof Words: 175
TotalNumberof Lines : 5
  • 단어 통계 정보 산출

2) File Write

In [15]:
f= open("./data/count_log.txt", 'w', encoding="utf8")
for i in range(1, 11):
    data= "%d번째 줄입니다.\n" % i
    f.write(data)
f.close()
  • mode='w', encoding='utf8'
  • 쓰기 모드고 인코딩은 utf-8이다
In [16]:
with open("count_log.txt", 'a', encoding="utf8") as f:
    for i in range(1, 11):
        data= "%d번째줄입니다.\n" % i
        f.write(data)
  • mode='a'는 추가 모드

OS Module

In [ ]:
import os
os.mkdir('log')
  • os 모듈을 사용하여 Directory 만들기
In [17]:
if not os.path.isdir('log'):
    os.mkdir('log')
else:
    print('log디렉토리는 이미 존재 합니다.')
log디렉토리는 이미 존재 합니다.
  • 디렉토리가 있는지 확인
In [18]:
os.path.isfile('count_log.txt')
Out[18]:
True
  • 파일이 있는지 확인
In [19]:
os.path.join('data','count_log.txt')
Out[19]:
'data\\count_log.txt'
  • join함수는 운영체제에 맞춰서 파일경로를 합쳐준다.

요즘에는 import pathlib을 많이 사용한다.

In [20]:
import os
if not os.path.isdir("log"):
    os.mkdir("log")
if not os.path.exists("log/count_log.txt"):
    f = open("log/count_log.txt", 'w', encoding="utf8")
    f.write("기록이 시작됩니다\n")
    f.close()

with open("log/count_log.txt", 'a', encoding="utf8") as f:
    import random, datetime
    for i in range(1, 11):
        stamp = str(datetime.datetime.now())
        value = random.random() * 1000000
        log_line = stamp + "\t" + str(value) +"값이 생성되었습니다"
        f.write(log_line)
  • Log 파일 생성하기
  • 디렉토리가 있는지 확인, 파일이 있는지 확인하고 만든다.

pickle

  • 파이썬의 객체를 영속화(persistence)하는 built-in 객체
  • 데이터, object등 실행중 정보를 저장 → 불러와서 사용
  • 저장해야하는 정보, 계산 결과(모델)등 활용이 많음
In [21]:
import pickle

f = open("list.pickle", "wb")
test = [1, 2, 3, 4, 5]
pickle.dump(test, f)
f.close()
  • 파일로 객체 저장
In [22]:
del test
In [23]:
test
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-23-4e1243bd22c6> in <module>
----> 1 test

NameError: name 'test' is not defined
  • test값을 삭제하고 없어 진걸 확인할 수 있다.
In [24]:
f = open("list.pickle", "rb")
test_pickle = pickle.load(f)
print(test_pickle)
f.close()
[1, 2, 3, 4, 5]
  • 저장된 파일을 불러와 읽으면 아까와 같은 값이 저장된걸 확인할 수 있다.
In [25]:
import pickle


class Mutltiply(object):
    def __init__(self, multiplier):
        self.multiplier = multiplier

    def multiply(self, number):
        return number * self.multiplier
In [26]:
muliply = Mutltiply(5)
muliply.multiply(10)
Out[26]:
50
In [27]:
f = open("multiply_object.pickle", "wb")
pickle.dump(muliply, f)
f.close()
In [28]:
del muliply
In [29]:
f = open("multiply_object.pickle", "rb")
multiply_pickle = pickle.load(f)
multiply_pickle.multiply(10)
Out[29]:
50


Log Handling

  • 프로그램이 실행되는 동안 일어나는 정보를 기록을 남기기
  • 유저의 접근, 프로그램의 Exception, 특정 함수의사용
  • Console 화면에 출력, 파일에 남기기, DB에 남기기 등등
  • 기록된 로그를 분석하여 의미있는 결과를 도출 할 수 있음
  • 실행시점에서 남겨야 하는 기록, 개발시점에서 남겨야하는 기록
  • 기록을 print로 남기는 것도 가능함
  • 그러나 Console창에만 남기는 기록은 분석시 사용불가
  • 때로는 레벨별(개발,운영)로 기록을 남길 필요도 있음
  • 모듈별로 별도의 logging을 남길필요도 있음
  • 이러한 기능을 체계적으로 지원하는 모듈이 필요함

logging level

image.png

In [30]:
import logging

logging.debug("틀렸잖아!")
logging.info("확인해")
logging.warning("조심해!")
logging.error("에러났어!!!")
logging.critical("망했다...")
WARNING:root:조심해!
ERROR:root:에러났어!!!
CRITICAL:root:망했다...
  • 지금 기본 logging level이 warning이상 이기때문에 3개가 나온다
In [31]:
import logging
logger = logging.getLogger("main")         #logger 선언
stream_hander = logging.StreamHandler()    #logger의 output 방법 선언
logger.addHandler(stream_hander)           #logger의 ouput 등록

logger.setLevel(logging.DEBUG)
logger.debug("틀렸잖아!")
logger.info("확인해")
logger.warning("조심해!")
logger.error("에러났어!!!")
logger.critical("망했다...")
틀렸잖아!
DEBUG:main:틀렸잖아!
확인해
INFO:main:확인해
조심해!
WARNING:main:조심해!
에러났어!!!
ERROR:main:에러났어!!!
망했다...
CRITICAL:main:망했다...
  • level을 DEBUG로 설정했기때문에 다 나온것을 확인 할 수 있다.

실제 프로그램을 실시 할때 여러 설정이 필요
데이터 파일 위치, 데이터 저장 장소, Operation Type 등
이러한 정보를 설정해줄 방법이 필요함

  1. configparser- 파일에 저장
  2. argparser- 실행시점에

1) configparser

  • 프로그램의 실행 설정을 file에 저장함
  • Section, Key, Value 값의 형태로 설정된 설정 파일을 사용
  • 설정파일을 DictType으로 호출후 사용
In [32]:
!type example.cfg
[SectionOne]
Status: Single
Name: Derek
Value: Yes
Age: 30
Single: True

[SectionTwo]
FavoriteColor = Green

[SectionThree]
FamilyName: Johnson
  • 값은 :=을 사용한다.
In [33]:
import configparser
config = configparser.ConfigParser()
config.sections()

config.read('example.cfg')
config.sections()

for key in config['SectionOne']:
    print(key)

config['SectionOne']["status"]
status
name
value
age
single
Out[33]:
'Single'

argparser

  • Console창에서 프로그램 실행시 Setting정보를 저장함
  • 거의 모든 Console기반 Python프로그램 기본으로 제공
  • 특수 모듈도 많이존재하지만(TF), 일반적으로 argparse를사용
  • Command-Line Option 이라고부름

image.png

In [34]:
!type arg_sum.py
import argparse

parser = argparse.ArgumentParser(description='Sum two integers.')

parser.add_argument('-a', "--a_value", dest="a", help="A integers", type=int)
parser.add_argument('-b', "--b_value", dest="b", help="B integers", type=int)

args = parser.parse_args()
print(args)
print(args.a)
print(args.b)
print(args.a + args.b)
  • 위 처럼 파일을 만든다.
  • 아래처럼 커맨드 창에서 실행을 한다.
In [35]:
!python arg_sum.py -a 10 -b 10
Namespace(a=10, b=10)
10
10
20
In [36]:
import logging

logger = logging.getLogger('myapp')
hdlr = logging.FileHandler('myapp.log')

formatter = logging.Formatter('%(asctime)s %(levelname)s %(process)d %(message)s')

hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)

logger.error('ERROR occurred')
logger.info('HERE WE ARE')
logger.info('TEST finished')
ERROR:myapp:ERROR occurred
INFO:myapp:HERE WE ARE
INFO:myapp:TEST finished
  • logging파일 format에 맞춰서 저장하기

'AI > 이론' 카테고리의 다른 글

Numpy part III  (0) 2021.01.25
Numpy part II  (0) 2021.01.25
Numpy part I  (0) 2021.01.25
Python data handling  (0) 2021.01.22
Module and Project  (0) 2021.01.21
Python Object Oriented Programming  (0) 2021.01.21
pythonic code  (0) 2021.01.20
python data structure  (0) 2021.01.20

+ Recent posts