<jupyter_start><jupyter_text>"CH05-2. 파이썬 날개달기"> Errors and Exceptions, Built-in Functions, The Python Standard Library 목차[05-4 Errors and Exceptions](05-4-예외처리)- [오류 예외 처리기법](오류-예외-처리-기법)- [오류 일부러 발생시키기](오류-일부러-발생시키기)- [예외 만들기](예외-만들기)    [05-5 Built-in Functions](05-5-내장-함수)[05-6 The Python Standard Library](05-6-라이브러리)  05-4 예외처리---프로그램을 만들다 보면 수없이 많은 오류를 만나게 된다. 물론 오류가 발생하는 이유는 프로그램이 잘못 동작하는 것을 막기 위한 파이썬의 배려이다. 하지만 때때로 이러한 오류를 무시하고 싶을 때도 있다. 이를 위해 파이썬은 try, except를 사용해서 예외적으로 오류를 처리할 수 있게 해준다. 오류 예외 처리 기법---자, 이제 유연한 프로그래밍을 위한 오류 처리 기법에 대해 살펴보자. try, except문다음은 오류 처리를 위한 try, except문의 기본 구조이다.```pythontry:    ...except [발생 오류[as 오류 메시지 변수]]:    ...```try 블록 수행 중 오류가 발생하면 except 블록이 수행된다. 하지만 try 블록에서 오류가 발생하지 않는다면 except 블록은 수행되지 않는다.except 구문을 자세히 살펴보자.> except [발생 오류 [as 오류 메시지 변수]]:위 구문을 보면 [ ] 기호를 사용하는데, 이 기호는 괄호 안의 내용을 생략할 수 있다는 관례 표기법이다. 즉 except 구문은 다음 3가지 방법으로 사용할 수 있다.--- 1. try, except만 쓰는 방법```pythontry:    ...except:    ...```이 경우는 오류 종류에 상관없이 오류가 발생하면 except 블록을 수행한다. 2. 발생 오류만 포함한 except문```pythontry:    ...except 발생 오류:    ...```이 경우는 오류가 발생했을 때 except문에 미리 정해 놓은 오류 이름과 일치할 때만 except 블록을 수행한다는 뜻이다. 3. 발생 오류와 오류 메시지 변수까지 포함한 except문```pythontry:    ...except 발생 오류 as 오류 메시지 변수:    ...```이 경우는 두 번째 경우에서 오류 메시지의 내용까지 알고 싶을 때 사용하는 방법이다.---  try, finallytry문에는 finally절을 사용할 수 있다. finally절은 try문 수행 도중 예외 발생 여부에 상관없이 항상 수행된다. 보통 finally절은 사용한 리소스를 close해야 할 때에 많이 사용한다.```pythonf = open('foo.txt', 'w')try:     무언가를 수행한다.finally:    f.close()```foo.txt 파일을 쓰기 모드로 연 후에 try문을 수행한 후 예외 발생 여부와 상관없이 finally절에서 f.close()로 열린 파일을 닫을 수 있다.---  여러개의 오류처리하기try문 안에서 여러 개의 오류를 처리하기 위해 다음 구문을 사용한다.```pythontry:    ...except 발생 오류1:   ... except 발생 오류2:   ...``` --- try문에 else절 사용하기try문에는 다음처럼 else절을 사용할 수 있다.```pythontry:    ...except [발생 오류[as 오류 메시지 변수]]:    ...else:   오류가 없을 경우에만 수행된다.    ...```try문 수행중 오류가 발생하면 except절이 수행되고 오류가 없으면 else절이 수행된다.---  오류 일부러 발생시키기프로그래밍을 하다 보면 종종 오류를 일부러 발생시켜야 할 경우도 생긴다. 파이썬은 raise 명령어를 사용해 오류를 강제로 발생시킬 수 있다.예를 들어 Bird 클래스를 상속받는 자식 클래스는 반드시 fly라는 함수를 구현하도록 만들고 싶은 경우(강제로 그렇게 하고 싶은 경우)가 있을 수 있다. 다음 예를 보자.```pythonclass Bird:    def fly(self):        raise NotImplementedError```위 예제는 Bird 클래스를 상속받는 자식 클래스는 반드시 fly 함수를 구현해야 한다는 의지를 보여 준다. 만약 자식 클래스가 fly 함수를 구현하지 않은 상태로 fly 함수를 호출한다면 어떻게 될까?> NotImplementedError는 파이썬 내장 오류로, 꼭 작성해야 하는 부분이 구현되지 않았을 경우 일부러 오류를 일으키기 위해 사용한다.```pythonclass Eagle(Bird):    passeagle = Eagle()eagle.fly()```Eagle 클래스는 Bird 클래스를 상속받는다. 그런데 Eagle 클래스에서 fly 함수를 구현하지 않았기 때문에 Bird 클래스의 fly 함수가 호출된다. 그리고 raise문에 의해 NotImplemented Error가 발생할 것이다.> 상속받는 클래스에서 함수를 재구현하는 것을 **메서드 오버라이딩**이라고 부른다.NotImplementedError가 발생되지 않게 하려면 다음과 같이 Eagle 클래스에 fly 함수를 반드시 구현해야 한다.```pythonclass Eagle(Bird):    def fly(self):        print("very fast")eagle = Eagle()eagle.fly()```위 예처럼 fly 함수를 구현한 후 프로그램을 실행하면 오류 없이 다음 문장이 출력된다.```pythonvery fast```<jupyter_code># 위의 예시에 대한 간단한 요약입니다.
# Bird 클래스를 상속받는 자식 클래스는 반드시 fly라는 함수를 구현하도록 만들고 싶은 경우
class Bird:
    def fly(self):
        raise NotImplementedError

# NotImplementedError가 발생되지 않게 하려면 다음과 같이 Eagle 클래스에 fly 함수를 반드시 구현해야 한다.

class Eagle(Bird):
    def fly(self):
        print("very fast")

eagle = Eagle()
eagle.fly()<jupyter_output>very fast<jupyter_text>예외 만들기---프로그램 수행 도중 특수한 경우에만 예외 처리를 하기 위해서 종종 예외를 만들어서 사용한다. 직접 예외를 만들어 보자.<jupyter_code># 예외는 다음과 같이 파이썬 내장 클래스인 Exception 클래스를 상속하여 만들 수 있다.
class MyError(Exception):
    pass
# 그리고 별명을 출력해 주는 함수를 다음과 같이 작성한다.
def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)
# 그리고 다음과 같이 say_nick 함수를 호출해 보자.
say_nick("천사")
say_nick("바보")
# 저장한 뒤 프로그램을 실행해 보면 다음과 같이 "천사"가 한 번 출력된 후 MyError가 발생한다.
# 이번에는 예외 처리 기법을 사용하여 MyError 발생을 예외 처리해 보자.
try:
    say_nick("천사")
    say_nick("바보")
except MyError:
    print("허용되지 않는 별명입니다.")

# 프로그램을 실행하면 다음과 같이 출력된다.
# 만약 오류 메시지를 사용하고 싶다면 다음처럼 예외 처리를 하면 된다.
try:
    say_nick("천사")
    say_nick("바보")
except MyError as e:
    print(e)<jupyter_output>천사<jupyter_text>하지만 프로그램을 실행해 보면 `print(e)`로 오류 메시지가 출력되지 않는 것을 확인할 수 있다. 오류 메시지를 출력했을 때 오류 메시지가 보이게 하려면 오류 클래스에 다음과 같은 `__str__` 메서드를 구현해야 한다. `__str__` 메서드는 print(e)처럼 오류 메시지를 print문으로 출력할 경우에 호출되는 메서드이다.<jupyter_code>class MyError(Exception):
    def __str__(self):
        return "허용되지 않는 별명입니다."
# 프로그램을 다시 실행해 보면 "허용되지 않는 별명입니다."라는 오류메시지가 출력되는 것을 확인할 수 있다.
try:
    say_nick("천사")
    say_nick("바보")
except MyError as e:
    print(e)<jupyter_output>천사
허용되지 않는 별명입니다.
{'fraction_non_alphanumeric': 0.10755148741418764, 'fraction_numerical': 0.006864988558352402, 'mean_word_length': 3.166825548141087, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '553361', 'license': 'Apache-2.0', 'n_tokens_mistral': 3104, 'n_tokens_neox': 4230, 'n_words': 701, 'path': '_notebooks/python/ch05-2-python.ipynb', 'repo_name': 'mn1121m/myblog', 'size': '4370'}