13주차 화 1114 (데코레이터, 가변형매개변) :: newb

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 13주차 화 1114 (데코레이터, 가변형매개변)
    광주인력개발원 일일포스팅(메모장) 2023. 11. 14. 16:38
    728x90
    반응형
    <데코레이터(Decorator)>
    
    함수의 재사용성을 확장한 개념의 방법
    <함수 실행 시간 확인하는 데코레이터 프로그램 작성>
    import time
    ### 데코레이터 함수 정의하기
    # =  func : 실제 처리할 함수 받아오는 매개변수
    def timer_decorator(func) :
        print(f"#1 : func = {func}")
        ### 실제 실행될 함수 정의 (함수 이름은 자유롭게)
        # - func로 받은 함수를 아래 함수로 재정의하게 됨
        def wrapper(*args, **kwargs) :
            # - tlwkrtlrks
            start_time = time.time()
            print(f"#2 : start_time = {start_time}")
    
            ### 실제 처리할 함수 : func
            rs = func(*args, **kwargs)
            print(f"#3 : rs = {rs}")
    
            #- 정료시간
            end_time = time.time()
            print(f"#4 : end_time = {end_time}")
    
            return rs
        print("#5 ------------------")
        return wrapper
    ### 데코레이터 호출 및 처리할 함수 정의하기
    # - 데코레이터 호출은 @를 사용함
    # = 데코레이터 함수 호출 시 밑에 정의된 함수(exe_function)가 자동으로 전달됨
    # - 데코레이터 함수가 리턴한 wrapper 함수는 exe_function 가 된다.
    #     (재정의 되는 시점)
    @timer_decorator
    def exe_function() :
        print("실제 처리할 함수")
        ### 2초간 대기 : 데코레이터가 처리되는 시간을 벌어주기 위해서
        time.sleep(2)
    #1 : func = <function exe_function at 0x0000022A81F058A0>
    #5 ------------------
    ### 실제 처리하기
    exe_function()
    #2 : start_time = 1699930617.996027
    실제 처리할 함수
    #3 : rs = None
    #4 : end_time = 1699930619.9973152
    <로그 데코레이터>
    def log_decorator(func) :
        print(f"#1 : func = {func}")
        def wrapper(*args, **kwargs) :
            print(f"Logo : {func.__name__} 함수 호출됨")
            rs = func(*args, **kwargs)
            print(f"Logo : {func.__name__} 함수 호출됨")
            return
        print("#2 ----------")
        return wrapper
    ### 데코레이터 호출 및 처리함수 정의
    @log_decorator
    def another_function() :
        print("여긴 어디? 넌 누구?")
    #1 : func = <function another_function at 0x0000022A82005580>
    #2 ----------
    ### 처리함수 호출
    another_function()
    Logo : another_function 함수 호출됨
    여긴 어디? 넌 누구?
    Logo : another_function 함수 호출됨
    <데코레이터 내부함수에섳 처리된 결과를 받아보기>
    def check_permission(param_id) :
        print(f"#1 : param_id = {param_id}")
        def decorator(func) :
            print(f"#2 : func = {func}")
            def wrapper(*args, **kwargs) :
                check_id = "admin"
                print(f"#3 : check_id = {check_id}")
    
                if check_id == param_id :
                    args = ["인증성공"]
                    print(f"#4 : args = {args}")
                    return func(*args, **kwargs)
    
                else :
                    print(f"#5 : raise명령으로 강제 오류 발생 ")
                    raise permissionError("접근 불기!!")
            print("#6 ------------")
            return wrapper
        print("#7 ------------")
        return decorator
    ### 데코레이터 호출 및 처리함수 정의
    @check_permission(param_id = "admin")
    def admin_function(rs_msg) :
        print(f"인증 결과 : {rs_msg}")
    #1 : param_id = admin
    #7 ------------
    #2 : func = <function admin_function at 0x0000022A8267C5E0>
    #6 ------------
    ### 처리함수 호출
    admin_function()
    #3 : check_id = admin
    #4 : args = ['인증성공']
    인증 결과 : 인증성공
    <영문 소문자 2개를 매개변수로 받아서, 대문자로 변환하는 데코레이터 프로그램>
    ### 함수이름 자유롭게..생성
    # = 데코레이터 함수 생성하셔서 대문자로 출력까지...
    def decorator_upper(func) :
        ### 인자로 넘어온 2개의 소문자는 args 매개변수가 받게됨
        def warpper(*args, **kwargs) :
            ### 인자로 넘겨받은 개의 소문자를 대문자로 처리하는 영역
            args = [arg.upper() for arg in args]
            ### 대문자로 변횐된 값 2개를 args에 리스트 타입으로 담아서 넘기면 됨
            return func(*args, **kwargs)
        
        return warpper
    ### 데코리이터 호출 및 처리 함수 정의
    @decorator_upper
    def getUpper(param1, param2) :
        print(f"대문자로 변환된 {param1} / {param2}")
    ### 처리하는 함수 호출 : 소문자 2개를 인자로 넘겨주기
    getUpper("abcd", "efgh")
    대문자로 변환된 ABCD / EFGH
    1 2
    ### 기본값(default) 정의 매개변수를 사용하는 함수
    def function2(a, b=3) :
        print(a, b)
    
    function2(4)
    4 3
    ### 키워드 정의 방식
    def function3(a, b) :
        print(a, b)
    
    function3(a=3, b=5)
    function3(b=6, a=4)
    3 5
    4 6
    ### 가변형 매개변수를 사용한 함수
    # 전달할 값이 몇개 일지 모를때 사용하는 방식
    def function4(*args) :
        print(args)
    
    function4(1,2,3,5)
    function4(1,2,3,6,9)
    (1, 2, 3, 5)
    (1, 2, 3, 6, 9)
    ### 가변 키워드 매개변수를 사용한 함수
    # 전달할 값이 몇개 일지 모를때 사용하는 방식
    def function5(**args) :
        print(args)
    
    function5(a=1,b=2,c=3)
    function5(a=1,b=2,c=3,d=6,e=9)
    
    dic = {"a" : 33, "b" : 55}
    function5(a =33, b = 55)
    function5(**dic)
    {'a': 1, 'b': 2, 'c': 3}
    {'a': 1, 'b': 2, 'c': 3, 'd': 6, 'e': 9}
    {'a': 33, 'b': 55}
    {'a': 33, 'b': 55}
    <실습> 어제 작성한 도서관리 프로그램을 데코레이터를 적용하기>
    class LibraryKiosk :
        def __init__(self) :
            self.books = {}
            print("클래스 생성 되었습니다.")
    
       # ------------------------------------------------------------------------
        ###도서입고 데코레이터 함수 정의하기
        def add_book_decorator(func) :
            def wrapper(self, book_id, title, quantity) :
                func(self, book_id, title, quantity)
            return wrapper
        
        def borrow_book_decorator(func) :
            def wrapper(self, book_id) :
                func(self, book_id)
            return wrapper
        def return_book_decorator(func) :
            def wrapper(self, book_id) :
                func(self, book_id)
            return wrapper
       # ------------------------------------------------------------------------
        @add_book_decorator
        def add_book(self, book_id, title, quantity) :
            if book_id in self.books :
                self.books[book_id]["quantity"] += quantity
            else :
                self.books[book_id] = {"title" : title, "quantity" : quantity}
    
            print(f"도서번호 : {book_id} / 제목 : {title} / 입고수량 : {quantity} 입고 성공")
    
        def borrow_book(self, book_id) :
            if (book_id in self.books) and (self.books[book_id]["quantity"] > 0) :
                self.books[book_id]["quantity"] -= 1
                print(f"도서번호 : {book_id} / 제목 : {self.books[book_id]['title']} / 남은재고수량 : {self.books[book_id]['quantity']}")
            else:
                print("도서가 존재하지 않거나, 대출할 재고가 없습니다.")
    
        def return_book(self, book_id) :
            if book_id in self.books :
                self.books[book_id]["quantity"] += 1
                print(f"도서번호 : {book_id} / 제목 : {self.books[book_id]['title']} / 남은재고수량 : {self.books[book_id]['quantity']}")
            else:
                print("해당 도서가 존재하지 않습니다. ")
    def main() :
        kiosk = LibraryKiosk()
        print(kiosk)
        while True:
            print("<도서 키오스크 메뉴>")
            print("1. 도서입고")
            print("2. 도서대출")
            print("3. 도서반납")
            print("4. 종료")
    
            choice = input("원하는 번호(1~4)를 선택하세요 : ")
    
            if choice == "1":
                book_id = input("도서 번호를 입력해 주세요: ")
                title   = input("도서 제목를 입력해 주세요: ")
                quantity= int(input("입고할 권수를 입력해 주세요: "))
                print(f"{book_id}/{title}/{quantity}")
    
                kiosk.add_book(book_id, title, quantity)
    
            elif choice == "2":
                print("대출 선택")
                book_id = input("대출할 도서번호를 입력해주세요 : ")
    
                kiosk.borrow_book(book_id)
    
            elif choice == "3":
                print("반납 선택")
                book_id = input("반납할 도서번호를 입력해주세요 : ")
    
                kiosk.return_book(book_id)
    
            elif choice == "4":
                print("종료 선택")
                break
            else:
                print("번호를 확인해주세요")
    if __name__ == '__main__' :
        main()

     

    728x90
    반응형
Designed by Tistory.