# [Python] 예외와 오류 관리

## 오류

---

### Error의 종류

[내장 예외](https://docs.python.org/ko/3.13/library/exceptions.html)

**문법 에러 Syntax Error**

```javascript
# Syntax Error
for i in range(10)
    print(i)
```

- 파이썬 코드를 실행하기 전에 발생하는 에러

- 코드 작성 시 오타나 문법적인 오류가 있을 경우 발생

- 인터프리터는 해당 줄에서 에러가 발생했음을 알려주며, 발견된 오류의 위치와 종류를 알려줌

**이름 에러 Name Error**

```javascript
# Name Error
print(x)
```

- 정의되지 않은 변수나 함수를 호출했을 때 발생

- 파이썬 이넡프리터는 해당 변수나 함수를 찾을 수 없다는 메시지를 출력

**타입 에러 Type Error**

```javascript
# Type Error
x = 10
y = '20'
print(x + y)
```

- 서로 다른 타입의 변수 간 연산이나 함수 호출 시 발생

- 파이썬 인터프리터는 해당 연산이나 함수 호출이 불가능하다는 메시지 출력

**인덱스 에러 Index Error**

```javascript
# Index Error
my_list = [1, 2, 3]
print(my_list[3])
```

- 리스트나 튜플 등의 시퀀스 타입에서 존재하지 않는 인덱스를 호출할 때 발생

- 파이썬 인터프리터는 해당 인덱스를 찾을 수 없다는 메시지를 출력

**키 에러 Key Error**

```javascript
# Key Error
my_dict = {'a':1, 'b':2}
print(my_dict['c'])
```

- 딕셔너리에서 존재하지 않는 키를 호출했을 때 발생

- 파이썬 인터프리터는 해당 키를 찾을 수 없다는 메시지를 출력

**값 에러 Value Error**

```javascript
# Value Error
int('a')
```

- 내장 함수나 메서드의 인자로 전달된 값의 타입이나 값이 유효하지 않을 때

- 파이썬 인터프리터는 해당 값을 처리할 수 없다는 메시지 출력

**재료 나누기 에러 ZeroDivisionError**

```javascript
# ZeroDivision Error
x = 10
y = 0
print(x / y)
```

- 0으로 나누기 연산을 수행할 때 발생

- 파이썬 인터프리터는 해당 연산이 불가능하다는 메시지를 출력

**어트리뷰트 에러 Attribute Error**

```javascript
# Attribute Error
my_list = [1, 2, 3]
print(my_list.append(4))
```

- 객체에 존재하지 않는 속성이나 메서드를 호출했을 때 발생

- 파이썬 인터프리터는 해당 메서드르르 찾을 수 없다는 메시지를 출력

**인자 개수 에러 TypeError**

```javascript
# Type Error
def add(x, y):
    return x + y

add(1, 2, 3)
```

- 함수나 메서드에 전달된 인자의 개수가 맞지 않을 때 발생

- 파이썬 인터프리터는 해당 함수나 메서드에 전달된 인자의 개수가 맞지 않다는 메시지를 출력

**파일 입출력 에러 File I/O Error**

```javascript
# File I/O Error
f = open('non-existent.txt', 'r')
f.read()
```

- 파일을 열거나 쓰거나 읽을 때 발생

- 파일이 존재하지 않거나 권한이 없는 경우 발생

- 파이썬 인터프리터는 해당 파일을 찾을 수 없다는 메시지를 출력

### 에러 발생시키기, 에러 반들기

**assert**

```javascript
test = 'hello'

assert test == 'hello', '에러 메시지 1' # 1
assert test == 'world', '에러 메시지 2' # 2
assert test + 3 == 5, '에러 메시지 3'   # 3
```

- 내가 설정한 조건에 만족하지 않을 경우 `AssertionError`를 발생

**raise**

```javascript
raise
raise ValueError
raise ValueError('코드를 잘~ 만들어주세요')
```

```javascript
try: 
    1/0
except ValueError:
    print('ValueError')
except ZeroDivisionError:
    print('ZeroDivisionError')

print(ZeroDivisionError)
print(type(ZeroDivisionError))
print(dir(ZeroDivisionError))
```

- raise를 사용하여 에러를 발생시킬 수 있다

- 에러별 분기도 가능하다

```javascript
class Leehojun(Exception): # Exception을 상속받으면 된다
    def __init__(self):
        super().__init__('입력된 값이 leehojun이 아닙니다.')
```

- 위와 같이 에러를 만드는 것도 가능하다

### 오류 처리와 로깅

- 로깅은 경고, 접근, 에러, 예외 처리, 특정 함수 사용 등에 대한 기록을 남김

- 주로 화면에 출력하거나 DB 또는 일반 plane text로 남기는 방식을 사용

- 로그 기록이 너무 많을 경우 시스템에 부하, 일반적인 펴집기가 읽지 못할 수있다

**logging**

```javascript
import logging

logging.basicConfig(level=logging.INFO) # 어느 레벨로부터 로깅할지, 기본으로 warning부터

logging.debug('This is a debug message')       # 고쳐야 할 코드, 기록 필요
logging.info('This is a info message')         # 정보성 메시지
logging.warning('This is a warning message')   # 경고 메시지
logging.error('This is an error message')      # 에러 메시지 (프로그램은 동작)
logging.critical('This is a critical message') # 프로그램 중지 (에러처리 안된경우)
```

- `logging` 모듈을 사용하면 다양한 레벨의 로그를 쉽게 남길 수 있다

### Traceback 역추적

- 파이썬 프로그램은 많은 모듈로 이루어져 있고 이 모듈은 내부에 있는 클래스나 함수를 가진다

- 서로서로 호출하는 관계가 있다 (스택에 이 정보가 보관)

- 예외적인 상황(에러)의 발생시점은 스택 추적(trace)을 통해 알 수 있다

- traceback이란 예외가 발생된 지점의 호출 연결 고리를 추적하는 스택 추정기능

## 예외 처리

---

- **예외 Exception**: 프로그램이 실행 중 예기치 않은 상황이 발생하여 프로그램이 종료되는 것

- **예외 처리**: 예외 상황에서 프로그램이 강제로 종료되는것을 방지하고 예외 상황을 처리 하는 방법

> google convention에서는 try와 except를 최소 단위로 사용하길 권고
에러가 나는 정확한 위치를 파악하기 위함

**try exception**

```javascript
try:
    # 예외가 발생할 가능성이 있는 코드
except:
    # 예외 처리 코드
```

- 파이썬에서는 `try-except` 구문을 사용하여 예외 처리

- try-except 구문을 사용하여 예외 처리 가능

- `try` 블록에서 예외가 발생하면 `except` 블록이 실행되고 프로그램 종료 X

**try except else finally**

```javascript
try:
    # 예외가 발생할 가능성이 있는 코드
except:
    # 예외 처리 코드
else:
    # 예외가 발생하지 않을 때 실행되는 코드
finally:
    # 예외 발생 여부와 상관없이 항상 실행되는 코드
```

- `try` 블록 내에서 예외가 발생하지 않으면 `else` 블록이 실행

- `finally` 블록은 예외 발생 여부와 상관 없이 항상 실행

**다양한 경우**

-   **try exception else**

```javascript
try:
    # 예외가 발생할 가능성이 있는 코드
except:
    # 예외 처리 코드
else:
    # 예외가 발생하지 않을 때 실행되는 코드
```

-   **try finally**

```javascript
try:
    # 예외가 발생할 가능성이 있는 코드
finally:
    # 예외 발생 여부와 상관없이 항상 실행되는 코드
```

-   **try except finally**

```javascript
try:
    # 예외가 발생할 가능성이 있는 코드
except:
    # 예외 처리 코드
finally:
    # 예외 발생 여부와 상관없이 항상 실행되는 코드
```

For the site tree, see the [root Markdown](https://slashpage.com/yerim-devnote.md).
