예외 처리와 내장 함수

변현섭·2023년 7월 28일
0

파이썬 기초 다지기

목록 보기
11/16
post-thumbnail

Ⅵ. 예외처리와 내장 함수

1. 예외 처리

1) try-except문

파이썬의 예외 처리 기법은 Java와 매우 비슷하다. 다만, Java에서는 try-catch문을 사용하지만, 파이썬에서는 try-except문을 사용한다. 이름만 다를 뿐 역할은 동일하다.

① try-except

  • 예외를 정의하지 않을 경우, 모든 오류에 대해 except 블록을 실행한다.
try:
    ...
except:
    ...

② 발생 오류를 정의한 경우

  • 발생 오류와 동일한 오류인 경우에만, except문을 실행한다.
try:
    ...
except 발생오류:
    ...

③ 발생 오류와 오류 변수를 포함하는 경우

  • Java의 문법과 가장 비슷한 방법으로, 예외 객체를 이용해야 할 때 사용한다.
try:
    ...
except 발생오류 as 오류변수:
    ...
  • 실사용 예시는 아래와 같다.
try:
    4 / 0
except ZeroDivisionError as e:
    print(e)

2) try-finally문

파이썬의 finally 역시 Java의 finally와 동일하기 때문에 자세한 설명은 생략하기로 한다.

try:
    f = open('foo.txt', 'w')
    # 무언가를 수행한다.

finally:
    f.close()  # 중간에 오류가 발생하더라도 무조건 실행된다.

3) try-else문

try-else는 파이썬에서 추가된 문법이다. try문을 실행하다 에러가 발생하면, except 블록으로 이동하고, 에러가 발생하지 않으면, else 블록이 실행된다.

try:
    age=int(input('나이를 입력하세요: '))
except:
    print('입력이 정확하지 않습니다.')
else:
    if age <= 18:
        print('미성년자는 출입금지입니다.')
    else:
        print('환영합니다.')

4) 예외를 강제로 호출하기

Java의 throw와 같은 기능으로 파이썬에서는 raise를 사용한다.

class Bird:
    def fly(self):
        raise NotImplementedError

위 예시는 자식 클래스의 fly 함수 구현을 강제하고 있는 것이다. 물론, 추상클래스로 정의하는 것이 더 일반적이긴 하나, 위와 같이 구현을 강제하는 경우도 간혹 있다.

5) 파이썬 예외 클래스

파이썬의 예외 클래스는 Java와 마찬가지로 모두 내장 예외 클래스인 Exception 클래스를 상속받아 정의된다. 파이썬은 다양한 내장 예외 클래스를 제공하는데, 대표적인 5가지 예외만 설명하기로 한다.

① ZeroDivisionError

  • 0으로 나누려고 할 때 발생하는 예외

② TypeError

  • 연산이나 함수가 잘못된 자료형의 객체에 적용될 때 발생하는 예외
  • 숫자와 문자열을 +로 합치려하는 등의 상황에서 발생

③ ValueError

  • 참조 값이 없을 때 발생하는 예외
  • 1부터 5까지 저장된 리스트에서 7을 remove하라는 명령을 내리거나, 7의 index를 찾으라는 명령을 내리는 등의 상황에서 발생

④ IndexError

  • ArrayIndexOutOfBounds와 동일한 예외

⑤ FileNotFoundError

  • 파일을 찾을 수 없을 때 발생하는 예외로, Java의 FileNotFoundException과 동일

6) 사용자 정의 예외

사용자 정의 예외 역시 Exception 클래스를 상속하여 만든다.

class MyError(Exception):
    pass

이제 사용자 정의 예외를 발생시켜보자.

def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)
    
say_nick("천사")
say_nick("바보")

say_nick("바보")가 실행되는 시점에서 예외가 발생한다. 하지만 예외를 발생시키는 것으로 함수를 종료시키면, 그냥 에러가 나는 것과 별반 다를게 없다. 프로그래머는 예외를 처리하여 사용자로 하여금 왜 에러가 발생한 것인지를 이해시켜주어야 한다. 그러므로 아래와 같이 발생한 예외를 처리까지 해주어야 한다.

try:
    say_nick("천사")
    say_nick("바보")
except MyError as e:
    print(e)

그런데 사실 위와 같이 print 함수로 예외를 처리하는은 경우, 예외 클래스에 __str__ 메서드를 먼저 구현해야 한다. 아래와 같이 __str__ 메서드를 정의하면, print문으로 오류 메시지를 출력할 수 있다.

class MyError(Exception):
    def __str__(self):
        return "허용되지 않는 별명입니다."

2. 내장 함수

내장 함수란, 별도의 import 없이 사용할 수 있는 함수로, print, del, type 등이 있다. 내장 함수의 종류는 매우 다양한데, 이 모든 걸 외워야한다는 느낌으로 보기보다는 한 번 봐둔다는 느낌으로 보고 넘기면 될 것 같다.

1) 숫자 관련 함수

① abs

  • 숫자의 절대값을 반환
>>> abs(-3)
3
>>> abs(-1.2)
1.2

② divmod

  • 두 개의 숫자를 입력받아 나눈 몫과 나머지를 튜플 형태로 반환
>>> divmod(7, 3)
(2, 1)

③ hex

  • 정수를 입력받아 16진수 문자열로 반환
>>> hex(234)
'0xea'

④ int

  • 문자열로 표현된 정수 또는 실수를 정수로 반환
  • 단, 문자열로 표현된 실수는 입력할 수 없음
>>> int('3')
3
>>> int(3.4)
3

⑤ max/min

  • iterable data-set을 받아 최대값/최소값을 반환
  • 문자열의 경우 사전 우위로 비교
>>> max([1, 2, 3])
3
>>> min([1, 2, 3])
1
>>> min("python")
'h'

⑥ oct

  • 정수를 8진수 문자열로 반환
>>> oct(34)
'0o42'

⑦ pow

  • 두 정수를 입력받아 제곱한 결과를 반환
  • ** 연산자를 사용하는 경우가 더 많아 pow의 사용빈도는 매우 낮음.
>>> pow(2, 4)
16

⑧ range

  • 입력 값이 하나일 경우, 0부터 해당 값 전까지를 iterable data-set으로 반환
>>> list(range(5))
[0, 1, 2, 3, 4]
  • 입력 값이 두 개일 경우, 시작 숫자부터 끝 숫자 전까지를 iterable data-set으로 반환
>>> list(range(5, 10))
[5, 6, 7, 8, 9]
  • 입력 값이 세 개일 경우, 세번째 입력 값은 숫자 간의 간격을 의미
>>> list(range(1, 10, 2))
[1, 3, 5, 7, 9]

⑨ round

  • 숫자를 입력받아 반올림한 결과를 반환
>>> round(4.6)
5
  • 입력 값이 두 개일 경우, 두번째 입력 값은 소수점 자리수를 의미
>>> round(5.678, 2)
5.68

⑩ sum

  • iterable data-set을 입력받아 데이터의 합을 반환
>>> sum([1,2,3])
6

2) 진위 판단 관련 함수

① all

  • iterable data-set을 입력받아 요소가 모두 참인지를 판단
>>> all([1, 2, 3])
True
>>> all([1, 2, 3, 0])
False

※ iterable data-set
리스트, 튜플, 문자열, 딕셔너리, 집합 등을 이르는 말로, 우리 말로는 순회 가능한 자료 집합이라 한다. 즉, 응용 for문을 사용할 수 있는 데이터 셋이다.

② any

  • all과 달리, 하나라도 참인지를 판단
>>> any([1, 2, 3, 0])
True
>>> any([0, ""])
False

③ filter

  • iterable data-set을 입력받아 각 요소를 필터링한 결과를 반환
def positive(x):
    return x > 0

print(list(filter(positive, [1, -3, 2, 0, -5, 6])))

[1, 2, 6]
  • lambda를 사용하여 아래와 같이 표현할 수도 있음
>>> list(filter(lambda x: x > 0, [1, -3, 2, 0, -5, 6]))
[1, 2, 6]

④ isinstance

  • 객체와 클래스를 입력받아 객체가 클래스의 인스턴스인지 판단
>>> a = Person()
>>> isinstance(a, Person)
True

3) 문자열 관련 함수

① chr

  • 유니코드 숫자를 입력받아 그 코드에 해당하는 문자를 반환
>>> chr(97)
'a'

② ord

  • chr과 반대로, 문자의 유니코드 숫자를 반환
>>> ord('a')
97

③ eval

  • 문자열로 구성된 표현식을 입력받아 해당 문자열의 실행 결과를 반환
>>> eval('1+2')
3
>>> eval("'hi' + 'a'")
'hia'
>>> eval('divmod(4, 3)')
(1, 1)

④ str

  • 입력 값을 문자로 반환
  • 문자는 어떤 자료형도 표현할 수 있기 때문에 사실상, 모든 자료형이 다 올 수 있으며, 실제로 사용할 일은 거의 없겠지만 iterable data-set도 올 수 있음
>>> str(3)
'3'

4) 연속된 데이터 반환 함수

① dir

  • 객체를 입력받아 해당 객체가 가지고 있는 메서드와 변수를 반환
>>> dir([1, 2, 3])
['append', 'count', 'extend', 'index', 'insert', 'pop',...]

② enumerate

  • iterable data-set을 받아 인덱스-value 쌍으로 변환하는 iterator를 반환
  • iterator는 리스트와 튜플로 변환할 수 있으며, 주로 for문과 함께 쓰임.
>>> for i, name in enumerate(['body', 'foo', 'bar']):
...     print(i, name)
...
0 body
1 foo
2 bar

③ list

  • iterable data-set을 받아 리스트로 반환
>>> list("python")
['p', 'y', 't', 'h', 'o', 'n']

④ tuple

  • iterable data-set을 받아 튜플로 반환
>>> tuple([1, 2, 3])
(1, 2, 3)

⑤ map

  • iterable data-set을 입력받아 각 요소에 함수를 적용한 결과를 반환
  • 개인적으로 정말 유용하고, 중요한 함수라고 생각함
>>> def two_times(x): 
...     return x*2
...
>>> list(map(two_times, [1, 2, 3, 4]))
[2, 4, 6, 8]

⑥ sorted

  • iterable data-set을 입력받아 데이터를 정렬 후, List로 반환
  • 문자열의 경우, 사전 우위로 비교
>>> sorted([3, 1, 2])
[1, 2, 3]

⑦ zip

  • 동일한 size의 iterable data-set을 입력받아 같은 인덱스의 데이터를 묶어서 튜플로 반환
  • size가 다를 경우, 가장 작은 size에 맞추어 순회하기 때문에 자료가 잘릴 수 있음
>>> list(zip([1, 2, 3], [4, 5, 6]))
[(1, 4), (2, 5), (3, 6)]
>>> list(zip([1, 2, 3], [4, 5]))
[(1, 4), (2, 5)]

5) 기타

① id

  • 객체를 입력받아 객체의 주소를 반환
>>> id(a)
135072304

② type

  • 객체를 입력받아 해당 객체의 자료형을 반환
>>> type("abc")
<class 'str'>
profile
Java Spring, Android Kotlin, Node.js, ML/DL 개발을 공부하는 인하대학교 정보통신공학과 학생입니다.

0개의 댓글