본문 바로가기
Python/개념

Day 7-3. 파이썬의 예외처리

by 사라리24 2024. 3. 18.
SMALL

1. 예외

예외(Exception)는 프로그램 실행  발생할  있는 예상치 못한 문제 또는 오류 상황을 의미합니다예외가 발생하면 프로그램은 중단되기 때문에 이를 적절하게 처리하여 중단을 방지하거나 오류에 대한 정보를 사용자에게 제공해야 합니다.
(ex) 프로그램 강제 중단 방지, 오류 확인

 

 
  
  print(10 / 3)
  print(5 / 0) # ZeroDivisionError: division by zero
  print(4 / 2)
 
 
3.3333333333333335
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-1-5340b6c8dc82> in <cell line: 2>()
      1 print(10 / 3)
----> 2 print(5 / 0) # ZeroDivisionError: division by zero
      3 print(4 / 2)

ZeroDivisionError: division by zero

ㄴ 5를 0으로 나눌 수 없으니 ZeoDivisiontError

 

* 오류 이름

 

ValueError

  • 잘못된 값을 함수나 연산에 제공할 때 발생합니다.
  • 예) 숫자가 아닌 문자열을 int() 함수로 변환하려고 할 때 발생.

TypeError

  • 올바르지 않은 유형의 객체를 연산에 사용하려 할 때 발생합니다.
  • 예) 문자열과 숫자를 함께 더하려고 할 때 발생.

ZeroDivisionError

  • 숫자를 0으로 나누려고 할 때 발생합니다.

IndexError

  • 리스트, 튜플, 문자열 등의 시퀀스 유형에서 범위를 벗어난 인덱스에 접근하려 할 때 발생합니다.
  • 예) 길이가 3인 리스트에 대해 4번째 요소에 접근하려고 할 때 발생.

KeyError

  • 딕셔너리에서 존재하지 않는 키를 사용하여 값을 검색하려고 할 때 발생합니다.

AttributeError

  • 객체에 없는 속성이나 메서드에 접근하려고 할 때 발생합니다.

FileNotFoundError

  • 존재하지 않는 파일을 열려고 할 때 발생합니다.

ImportError

  • 존재하지 않는 모듈을 가져오려고 할 때 또는 모듈 내에 해당 속성/함수가 없을 때 발생합니다.

NameError

  • 정의되지 않은 변수나 함수를 사용하려고 할 때 발생합니다.
  • 예) 프로그램에서 정의되지 않은 변수 x를 사용하려고 할 때 발생.

OverflowError

  • 수치 연산 결과가 너무 커서 표현할 수 없을 때 발생합니다.

MemoryError

  • 프로그램이 사용 가능한 모든 메모리를 소진했을 때 발생합니다.

 

2. 예외 처리 기본 구조

 

  
  try:
      # 예외가 발생할 가능성이 있는 코드

  except ExceptionType1:  # 'ExceptionType1'에는 실제 예외 유형이 들어갑니다.
      # ExceptionType1 예외가 발생했을 때 실행될 코드

  except ExceptionType2:  # 'ExceptionType2'에는 다른 예외 유형이 들어갑니다.
      # ExceptionType2 예외가 발생했을 때 실행될 코드

    # 추가적인 except 블록을 계속 추가할 수 있습니다.
  
  else:
      # try 블록에서 예외가 발생하지 않았을 때 실행될 코드

  finally:
      # 예외 발생 여부와 관계없이 항상 실행될 코드
 

 

 

1. 모든 예외 처리하기

  
  try:
      print(10 / 3 # 정상적으로 실행
      print(5 / 0)     # 오류/오류메세지 출력/프로그램종료
      print(4 / 2)      
  except ZeroDivisionError :
      print('0으로 나눌 수 없습니다')
   print('프로그램을 종료합니다')


3.3333333333333335
0으로 나눌 수 없습니다
프로그램을 종료합니다

ㄴ오류가 뜨면 밑에는 실행되지 않은 채로 프로그램이 종료됩니다.

ㄴexcept옆에 오류 이름을 적고 밑에 실행문을 적습니다.

ㄴexcept 밖에 있는 실행문은 오류가 뜨지 않아도 출력됩니다.

 

 
  try:
    print(10 / 3)
    print(5 / 0)
    print(4 / 2)
 
  except : # 뒤에 이름을 명시 안해도 됨
                # exeption이라는 클래스(부모 클래스)에서 모든 오류를 다 상속하고 있기 때문에
 
      print('0으로 나눌 수 없습니다')
 
  print('프로그램을 종료합니다')
 
3.3333333333333335
0으로 나눌 수 없습니다
프로그램을 종료합니다

  except ZeroDivisionError : //  except  동일하게 출력됩니다. 

 

  
  data = [10, 20, 30, 40, 50]

  try:
      data = [10, 20, 30, 40, 50]
      print(data[0]) #실행
      print(data[5]) #에러 // IndexError : list index out of range
      print(data[3]) #실행
 
  except :
      print('인덱스 지정이 올바르지 않습니다')
 
  print('프로그램을 종료합니다')


10
인덱스 지정이 올바르지 않습니다
프로그램을 종료합니다

ㄴ   except  IndexError : //  except  동일하게 출력됩니다. 

 

 

2. 특정 예외 처리하기

  
 
  try:
      data = [10, 20, 30, 40, 50]
      print(data[0])
      print(int('일')) #에러 : ValueError except 가 없어서 오류
      print(5/0)       #에러 : IndexError
      print(data[5]) #에러 : ZeroDivisionError
      print(data[3])
 
 
 
  except IndexError:
      print('인덱스 지정이 올바르지 않습니다')
 
  except ZeroDivisionError:
      print('0으로 나눌 수 없습니다')
 
  print('프로그램을 종료합니다')
 


 
10
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-21-6d519616d88a> in <cell line: 1>()
      2     data = [10, 20, 30, 40, 50]
      3     print(data[0])
----> 4     print(int('일')) 
      5     print(5/0) 
      6     print(data[5]) 

ValueError: invalid literal for int() with base 10: '일'

 

  
 
  try:
      data = [10, 20, 30, 40, 50]
      print(data[0])
      print(int('일'))  #에러 : ValueError except 
      print(5/0)        #에러 : IndexError
      print(data[5])  #에러 : ZeroDivisionError
      print(data[3])
 
 
  except IndexError:
      print('인덱스 지정이 올바르지 않습니다')
 
  except ZeroDivisionError:
      print('0으로 나눌 수 없습니다')
 
  except ValueError: -> # 추가되면 오류뜨지 않음 // 순서는 중요하지 않음
      print('문자열을 정수로 변환했습니다.')  
 
  print('프로그램을 종료합니다')
 


 
10
문자열을 정수로 변환했습니다.
프로그램을 종료합니다

 

 
 
  try:
      data = [10, 20, 30, 40, 50]
      print(data[0])
      print(int('일')) 
      print(5/0) 
      print(data[5]) 
      print(data[3])
   
  except :                                 ------------------>  #위에 있으면 오류
      print('인덱스 지정이 올바르지 않습니다')

  except IndexError:
      print('인덱스 지정이 올바르지 않습니다')

  except ZeroDivisionError:
      print('0으로 나눌 수 없습니다')

  except ValueError:
      print('문자열을 정수로 변환했습니다.')  

  print('프로그램을 종료합니다')
 
 
File "<ipython-input-51-9bab777718a0>", line 9
    except : #위에 있으면 오류
    ^
SyntaxError: default 'except:' must be last
 
 
  try:
      data = [10, 20, 30, 40, 50]
      print(data[0])
      print(int('일')) 
      print(5/0) 
      print(data[5]) 
      print(data[3])
   
  except IndexError:
      print('인덱스 지정이 올바르지 않습니다')
 
  except ZeroDivisionError:
      print('0으로 나눌 수 없습니다')
 
  except ValueError:
      print('문자열을 정수로 변환했습니다.')  
 
  except :                    -----> 제일 아래에 위치 (오류발생X)
      print('인덱스 지정이 올바르지 않습니다')
 
  print('프로그램을 종료합니다')
 
 
10
문자열을 정수로 변환했습니다.
프로그램을 종료합니다

 

 

 

3. 예외 에러 메세지 받기 (Exception as e)


try:

    오류가 일어날 수 있는 코드

except 오류이름 as e:
    print(e)

  
 
 
  try:
    print(data[0])
    print(int('일')) 
    print(5/0) 
    print(data[5]) 
    print(data[3])

  except IndexError as e:
      print(e)  
  except ZeroDivisionError as e:
      print(e)
  except Exception as e: # 어떤 오류가 났는지 e에 담기게 됨 (객체로)
      print(e)                      # 에러객체의 타입은 str
 
  print('프로그램을 종료합니다')  
 
 
 
10
invalid literal for int() with base 10: '일'
프로그램을 종료합니다

 

  • except:만 사용: 하면 프로그램 종료나 키보드 중단과 같은 특수한 예외까지 처리할 수 있지만, 대부분의 상황에서 이렇게 예외 처리는 권장되지 않습니다.
  • except Exception as e:는 일반적인 예외만 처리하면서, 발생한 예외의 상세 정보에 접근할 수 있는 능력을 제공합니다. 이 형태를 사용하면 더 명시적이며 예외 처리가 더 예측 가능해집니다.

 

 

4. 예외가 발생하지 않았을 경우 처리하기

try:
    오류가 일어날 수 있는 코드

except :
     오류가 일어날 경우 실행문


else: <-----------------------
     오류가 일어나지 않았을 경우 실행문
 
  try:
    print(data[0])
    print(data[3])

  except IndexError as e:
      print(e)  
  except ZeroDivisionError as e:
      print(e)
  except Exception as e: 
      print(e)           
 
  else:
    print('오류 관계없이 무조건 실행되는 문장')  
 
  print('프로그램을 종료합니다')  
 
 

ㄴ else

10
40
오류 관계없이 무조건 실행되는 문장
프로그램을 종료합니다

 

 

 

5. 예외 발생 여부와 관계없이 실행하기

try:
    오류가 일어날 수 있는 코드

except :
     오류가 일어날 경우 실행문


else: 
     오류가 일어나지 않았을 경우 실행문

finally: <-----------------------
     오류에 관계없이 무조건 실행되는 실행문

      
 
  try:
    print(data[0])
    print(data[5])
    print(data[3])

  except IndexError as e:
      print(e)  
  except ZeroDivisionError as e:
      print(e)
  except Exception as e:
      print(e)          
 
  else:
    print('오류 관계없이 무조건 실행되는 문장')  
 
  finally:
    print('오류에 관계없이 무조건 실행되는 문장')
 
  print('프로그램을 종료합니다')  
 
10
list index out of range
오류에 관계없이 무조건 실행되는 문장
프로그램을 종료합니다

 

 

 

4. Exception 클래스

  Exception 클래스는 파이썬의 내장 예외 계층 구조에서 거의 모든 내장 예외의 기본 클래스입니다 클래스는 사용자 정의 예외를 만들거나 특정 예외 유형을 잡기 위한 기본적인 인터페이스를 제공합니다. (모든 에러의 부모클래스, 우리가 에러를 만들 수도 있다, )

 

1. 상속: 예외 유형은 Exception을 상속받아서 정의됩니다. 예를 들면 ValueError, TypeError, FileNotFoundError 등이 있습니다. 이 상속 구조 덕분에 except Exception 블록은 Exception을 상속받은 모든 예외를 캡처할 수 있습니다.

2. 메시지: 예외가 생성될 때, 일반적으로 오류 메시지를 함께 전달할 수 있습니다. 이 메시지는 예외 객체의 args 속성을 통해 접근 가능하며, 예외를 문자열로 변환할 때(예: str(e)) 해당 메시지가 반환됩니다. ( str-생략가능 print(e ))

 

  raise Exception or 오류이름 ("    ")

 

 
  try:
      raise Exception("에러가 발생했어요.")
  except Exception as e:
      print(e)
 
에러가 발생했어요.

 

 
  def func1():
      n = int(input('짝수를 입력하세요: '))
      if n % 2 != 0:
          raise Exception('짝수가 아닙니다')
      print(n)

  try:
      func1()
  except Exception as e:
      print('예외가 발생했습니다', e)
 
짝수를 입력하세요: 45
예외가 발생했습니다 짝수가 아닙니다

 

 
  def func1():
     func2()

  def func2():
      func3()

  def func3():
      print('%d' % '문자열 출력')

  func1()
 

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-41-a6699e9f524b> in <cell line: 10>()
      8     print('%d' % '문자열 출력')
      9 
---> 10 func1()

2 frames
<ipython-input-41-a6699e9f524b> in func3()
      6 
      7 def func3():
----> 8     print('%d' % '문자열 출력')
      9 
     10 func1()

TypeError: %d format: a real number is required, not str

 

 
  def func1(): #(2)  
      func2()

  def func2(): #(3)
      func3()

  def func3(): #(4)
      print('%d' % '문자열 출력')

  func1() #(1)        

  # (5)없다

  # Q. 에러가 뜨지 않게 오류처리 어디서 해야 할까?
  # A.  (1)(2)(3)(4) 어디서든 가능
 

 

 
  def func1():
      try:
          func2()
      except TypeError :
          print('타입이 올바르지 않습니다.')
 
  def func2(): 
      func3()

  def func3(): 
      print('%d' % '문자열 출력')

  func1()
 
타입이 올바르지 않습니다.
 
  def func1():
      func2()

  def func2():
      func3()

  def func3():
      try:
          print('%d' % '문자열 출력')
      except TypeError:
          print('타입이 올바르지 않습니다!')

  func1()
 
타입이 올바르지 않습니다.

ㄴ 어디에 (1) (2) (3) (4) 어디에 넣어도 에러 오류처리가 가능합니다.

 

5. 사용자 정의 예외 클래스를 직접 만들고 활용하기

 
 
  # AgeLimitError 오류 클래스 만들기
  class AgeLimitError(Exception)
      def __init__(self, age, message="원하는 나이 범위가 아님!"):
          self.age = age
          super().__init__(message) #부모 Exception class로 message를 던져줄 것
 

  def check_age(age):
      if age < 20
          raise AgeLimitError(age, "나이 범위보다 어림") #일부러 오류발생
 
         # 메모리에 올리자마자 실행(변수에 담지 않음!)
        # ale = AgeLimitError(age, "나이 범위보다 어림")
           raise ale (실행가능하지만 사용하지 않음)
 
      elif age > 40:
         raise AgeLimitError(age, "나이 범위보다 큼")  #일부러 오류발생
      else:
          return "나이 범위 안에 포함!"
 

  ages = [17, 60, 46, 20, 52, 26]
 

  for age in ages:
      try:
          print(check_age(age))     # 여기에 ages 들 차례대로 들어옴
      except AgeLimitError as e# 에러가 발생하면 실행문 출력
          print(f"Error for age {e.age}: {e}"#e.age / e가 객체



Error for age 17: 나이 범위보다 어림
Error for age 60: 나이 범위보다 큼
나이 범위 안에 포함!
나이 범위 안에 포함!
Error for age 52: 나이 범위보다 큼
나이 범위 안에 포함!

'Python > 개념' 카테고리의 다른 글

Day 7. 과제_주민번호 유효성 검사  (0) 2024.03.20
Day 6. 과제_가위바위보  (0) 2024.03.18
Day 7-2. 파이썬 스페셜(매직) 메소드  (0) 2024.03.18
Day 7-1. 파이썬 상속  (0) 2024.03.18
Day 6-3. 객체지향과 클래스  (0) 2024.03.18