7일차 복습_패키지모듈, 예외처리

yyy·2024년 1월 5일

07.패키지_모듈

1. import란

: import는 '수입하다', '가져오다' 라는 의미를 가지고 있다. 컴퓨터에서는 파이썬 모듈 파일에 정의된 변수, 함수, 클래스들을 사용하기 위해 파이썬 실행환경에 등록하는 작업을 의미한다.

2. Import 구문

1) 모듈 import

  • 하나의 모듈을 import 할 때

    import 모듈

    예시)

    import test_module
    
  • namespace의 이름을 모듈명이 아니라 별칭으로 지정 : import 모듈 as 별칭

    예시)

    import my_module as mm
    
  • 여러 개의 모듈을 import 할 때

    import 모듈1, 모듈2

  • 모듈을 import 하고 그 안에 함수, 클래스를 사용할 때는 모듈명이 namespace의 이름이 되므로,

    모듈명.함수(), 모듈명.class

    구문으로 호출한다.

2) 모듈내의 특정 항목만 import

  • from 모듈 import 함수
  • from 모듈 import 클래스
  • from 모듈 import 함수1, 함수2, 클래스
  • from 모듈 import *

-> * 를 이용하면 그 모듈의 모든 함수/클래스들을 현재 실행중인 namespace에 추가해 사용할 수 있게 해준다. 이 방식은 이름 충돌의 가능성이 있기때문에 추천되지 않는다.

※ import module vs from module import *

  • import module : : module을 불러오는 것
  • from module import : : module로부터 모두() import 하는 것
    둘 다 같은 의미인 것 같지만 다른 의미이다.

① import module은 모듈 안의 함수를 사용할 때

모듈명.함수명()

② from module import * 은 모듈 안의 함수를 사용할 때

함수명()

으로 사용한다.

예시)
my_package의 calculator

def plus(num1,num2):
    return num1 + num2

def minus(num1,num2):
    return num1 - num2

def multipy(num1,num2):
    return num1 * num2

def divide(num1,num2):
    return num1 / num2
  • import module 을 사용했을 때

    from my_package import calculator
    print(calculator.plus(100,200)) 
    
  • from module import * 을 사용했을 때

    from my_package.calculator import *
    print(plus(1,1),divide(1,100))

3) 패키지에 속한 모듈 import

  • import 패키지명. 모듈
  • from 패키지명 import 모듈
  • from 패키지명 import 모듈1, 모듈2
  • from 패키지명. 모듈 import 함수
  • from 패키지명. 모듈 import 클래스
  • from 패키지명. 모듈 import 함수1, 함수2, 클래스
  • from Root 패키지. Sub 패키지1. sub 패키지2. 모듈 import 함수
  • from Root 패키지. Sub 패키지1. Sub 패키지2. 모듈 import 클래스
  • 패키지에 속한 모듈을 import 할때 : from 절에 패키지, import 절에 모듈 설정
  • import 가능한 것 : 모듈, 변수, 함수, 클래스

3. import 된 모듈 찾는 경로 및 pythonpath

  • sys 모듈 : 파이썬을 설치할 때 함께 설치되는 라이브러리 모듈로, sys 모듈을 사용하면 파이썬 라이브러리가 설치되어 있는 디렉터리를 확인할 수 있다.

    예시)

    import sys 
    from pprint import pprint 
    pprint(sys.path) 
    
  • sys.path : 파이썬 라이브러리가 설치되어 있는 디렉터리를 보여준다. 만약 파이썬 모듈이 위 디렉터리에 들어있다면 모듈이 저장된 디렉터리로 이동할 필요 없이 바로 불러서 사용할 수 있다.

    ※ pprint() : 자료구조를 보기좋게 한줄로 정렬해주는 함수이다.

    예시-결과)

    ['C:\\classes\\01_python_basic',
     'C:\\Users\\user\\anaconda3\\python311.zip',
     'C:\\Users\\user\\anaconda3\\DLLs',
     'C:\\Users\\user\\anaconda3\\Lib',
     'C:\\Users\\user\\anaconda3',
     '',
     'C:\\Users\\user\\anaconda3\\Lib\\site-packages',
     'C:\\Users\\user\\anaconda3\\Lib\\site-packages\\win32',
     'C:\\Users\\user\\anaconda3\\Lib\\site-packages\\win32\\lib',
     'C:\\Users\\user\\anaconda3\\Lib\\site-packages\\Pythonwin']
  • 위의 경로 이외에 파이썬 모듈이 있을 경우 PYTHONPATH 환경변수에 그 디렉토리 경로를 등록한다.
    예시)

    ① 파일탐색기 c 드라이브 source 파일에 test_module 생성

    %%writefile "c:\source\test_module.py" 
    def hello_world():
        print("hello world")

    ② sys.path.append를 사용해서 'C:\source' 라는 디렉터리를 sys.path에 추가한다. (=import할 대상의 시작(root)경로를 추가)

    import sys 
    sys.path.append(r"C:\source") 

    ③ sys.path를 보면 가장 마지막 요소에 'C:\source' 가 추가된 것을 볼 수 있다.

['C:\\classes\\01_python_basic',
   'C:\\Users\\user\\anaconda3\\python311.zip',
   'C:\\Users\\user\\anaconda3\\DLLs',
   'C:\\Users\\user\\anaconda3\\Lib',
   'C:\\Users\\user\\anaconda3',
   '',
   'C:\\Users\\user\\anaconda3\\Lib\\site-packages',
   'C:\\Users\\user\\anaconda3\\Lib\\site-packages\\win32',
   'C:\\Users\\user\\anaconda3\\Lib\\site-packages\\win32\\lib',
   'C:\\Users\\user\\anaconda3\\Lib\\site-packages\\Pythonwin',
   'C:\\source']

메인모듈(main module)과 하위모듈(sub module)

  • 메인 모듈
    • 현재 실행하고 있는 모듈
    • python 모듈.py로 실행된 모듈을 말한다.
  • 하위 모듈
    • 메인모듈에서 import 되어 실행되는 모듈
    • 모듈을 import하면 그 모듈을 실행시킨다. 이때 모듈에 있는 실행코드들도 같이 실행된다. 이것을 방지하기 위해 모듈이 메인 모듈로 실행되는지 하위모듈로 실행되는지 확인이 필요하다
  • name 내장 전역변수
    • 실행중인 모듈명을 저장하는 내장 전역변수
    • 만약 메인모듈이라면 'main', 하위모듈이라면 모듈명(파일명)이 저장된다.
    • 모듈이 메인 모듈로 시작하는지 여부확인할 때 사용한다.
    • 메인모듈일 때만 실행할 코드블록

if name == 'main':

예시)
mod1.py

def add(a,b):
    return a + b
def sub(a,b):
    return a - b
print(add(1,4))
print(sub(4,2))
import mod1

이것을 실행하면

import mod1

5
2

단지 mod1.py 파일의 add,sub 함수만 사용하려고 했는데도 mod1.py가 실행되어 5, 2라는 결과값을 출력한다.
이러한 문제를 방지하기 위해서는 mod1.py 파일을 다음과 같이 변경해야 한다.

def add(a,b):
    return a + b
def sub(a,b):
    return a - b
if __name__ == "__main__" :
    print(add(1,4))
    print(sub(4,2))

if name == "main" 는 name == "main"이 참이 되었을때만 다음 문장이 수행되고 거짓일때는 다음문장이 수행되지 않는다.

그래서 다시 실행해 보면

import mod1

아무것도 출력되지 않는다.

3rd party library 설치

  • 모듈(module) : 기능을 모아 놓은 것
  • 패키지(package) : 모듈을 모아 놓은 것
  • 라이브러리(library) : 패키지드을 모아 놓은 것
    • library는 누구든 만들어서 배포할 수 있다.
      • 1st party library: 파이썬 실행 환경 설치시 내장되어 있는 library
      • 2nd party library: Application을 만들면서 필요에 따가 정의한 library (내가 만든 라이브러리)
      • 3rd party library: 개인이나 회사 또는 단체에서 만들어 배포한 library.

08_예외처리(exception handling)

오류

  • 함수나 메소드가 처리 도중 다음 명령문을 실행할 수 없는 상황
  • 오류 중 처리가능한 것을 Exception(예외) 라고 한다. 그리고 그 예외를 처리하는 것을 Exception Handling 이라고 한다

1. 오류의 종류

  • 파이썬 문법을 어겨서 발생하는 오류
    • 코드를 수정해야 한다
  • 실행 환경의 문제로 발생하는 오류
    • 코드상에서는 Exception의 발생여부를 확신할 수 없다.
    • 만약 발생할 경우 어떻게 처리할지를 구현해야 한다.

2. exception handling

  • Exception이 발생되어 프로그램이 더 이상 실행될 수 없는 상황을 처리(handling)해서 정상화 시키는 작업이다.
  • try - except 구문을 이용해 처리한다.

1) try, except 구문

try:
    Exception 발생가능한 코드 블록
except [Exception클래스 이름 [as 변수]] :
    처리 코드 
  • try 블록 수행 중 오류가 발생하면 except 블록이 수행된다. 하지만 try 블록에서 오류가 발생하지 않는다면 except 블록은 수행하지 않는다.
(1) try, except만 쓰는 방법

: 오류의 종류에 상관없이 오류가 발생하면 except 블록을 수행한다.

try:
...
except:
...
(2) 발생오류만 포함한 Except 문

: except문에 미리 정해 놓은 오류 이름과 일치할 때만 except 블록을 수행한다.
ex)

try:
...
except 발생오류:
...
(3) 발생오류와 오류 메시지 변수까지 포함한 except 문

: (2) 번에서 오류 메시지의 내용까지 알고 싶을 때 사용
ex)

try:
...
except 발생오류 as 오류 메시지 변수:

예시)

try:
    4/0
except ZeroDivisionError as e:
    print(e)

예시-결과)

division by zero

-> 4를 0으로 나누려고 하면 ZeroDivisionError가 발생하는데, 이때 except 블록이 실행되고 변수 e에 담기는 오류 메시지를 출력하면 이와 같이 나온다.

2) finally 구문

  • finally 절은 try문 수행 도중 예외 발생 여부에 상관없이 항상 수행된다. 보통 finally 절은 사용한 리소스를 close해야 할 때 많이 사용한다.
  • try 구문에 반드시 실행되야 하는 코드블록을 작성할때 사용한다.

예시)

print("시작")
try:
    print(1)
    print(2)
    print(aaaaa)
except NameError:
    print(3)
finally:
    print("정상코드-반드시 실행되어야함")

print("종료")

예시-결과)
시작
1
2
3
정상코드-반드시 실행되어야함
종료

2. exception 발생시키기

1) 사용자 정의 exception 클래스 구현

  • 파이썬은 exception 상황을 클래스로 정의해 사용한다.
    • exception이 발생하는 상황과 관련된 attribute들과 메소드들을 정의한 클래스
      예시)
      월에 1 ~ 12 이외의 값이 대입되었을 때 발생시킬 Exception class 정의
class InvalidMonthException(Exception):
    def __init__(self, invalid_month):
        self.invalid_month = invalid_month
        
    def __str__(self):
        return f"{self.invalid_month}는 잘못된 월입니다. 1~12 사이의 값을 넣으시오"

그리고 month에 500 할당

month = 500 
raise InvalidMonthException(500)

예시-결과)

InvalidMonthException                     Traceback (most recent call last)
Cell In[38], line 2
      1 # exception 발생
----> 2 raise InvalidMonthException(500)

InvalidMonthException: 500는 잘못된 월입니다. 1~12 사이의 값을 넣으시오

오류가 생긴다.

2) exception 발생시키기

  • 함수나 메소드가 더이상 작업을 진행할 수 없는 조건이 되면 exception을 강제로 발생시킨다.

3) raise 구문

(1) exception을 강제로 발생시킨다.
  • 업무규칙을 어겼거나 다음 명령문을 실행할 수 없는 조건이 되면 진행을 멈추고 caller로 요청에게 작업을 처리 못했음을 알리며 돌아가고자 할때 exception을 발생한다.

    raise Exception 객체

(2) raise vs return
  • return : 정상적으로 끝나서 돌아가는 의미. 처리결과가 있으면 그 값을 가지고 돌아간다.
    • caller는 그 다음 작업을 이어서 하면 된다.
  • raise : 실행도중 문제(exception)가 생겨 비정상적으로 끝나서 돌아가는 의미. 비정상적인 상황정보를 가지는 exception 객체를 반환값을 가지고 돌아간다.
    • caller는 try-except 구문으로 발생한 exception을 처리하여 프로그램을 정상화하거나, 자신도 caller에게 exception을 발생시키는 처리를 한다.
(3) 오류 일부러 발생시키기
  • 파이썬은 raise 명령어를사용해 오류를 강제로 발생시킬 수 있다. 예시1)
    class Bird:
      def fly(self):
          raise NotimplementedError
    class Eagle(Bird):
      pass
※ NotimplementedError : 파이썬 내장 오류로, 꼭 작성해야 하는 부분이 구현되지 않았을 경우, 일부러 오류를 일으키기 위해 사용한다.

eagle = Eagle()
eagle.fly()





-> Eagle 클래스는 Bird 클래스를 상속받기 때문에 Fly 함수 구현이 가능하다. 하지만 raise문에 의해 NotimplementedError 오류가 일부러 발생된다.

def save_month(month):

if month < 1 or month > 12:
    print("저장할 수 없음")
    return
print(f"월로 {month}를 저장합니다.")  

def save_day(day):
print(f"일로 {day}를 저장합니다.")




save_month(220)
save_day(3)


예시2-결과)
저장할 수 없음
일로 3를 저장합니다.

-> 이렇게 월은 220 숫자가 들어가서 저장할 수 없지만 일은 저장이 된다. 하지만 월이 저장이 안되면 일도 저장이 안되야 하기 때문에 구문을 바꿔준다.

예시2-1)

def save_month(month):
if month < 1 or month > 12:
raise InvalidMonthException(month)
print(f"월로 {month}를 저장합니다.")

def save_day(day):
print(f"일로 {day}를 저장합니다.")

try:
save_month(-10)
save_day(3)

except:
print('처리')

save_month(220)
save_day(3)


예시2-1-결과)

NameError Traceback (most recent call last)
Cell In[74], line 1
----> 1 save_month(220)
2 save_day(3)

Cell In[73], line 13, in save_month(month)
2 """ 월을 저장하는 함수
3 Parameter:
4 month: int - 저장할 월
(...)
8
9 """
11 if month < 1 or month > 12:
12 # print("저장할 수 없음")
---> 13 raise InvalidMonthExcption(month)
14 print(f"월로 {month}를 저장합니다.")

NameError: name 'InvalidMonthExcption' is not defined



           
  

0개의 댓글