ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Decorator / contextmanager
    python/기본 2022. 4. 29. 20:24
    def add_num(a, b):
        return a + b
    
    
    print('start')
    r = add_num(1, 2)
    print('end')
    
    print(r)
    
    
    ####################################################################
    # AOP 처럼 ...
    def print_info(func):
        def wrapper(*args, **kwargs):
            print('start')
            result = func(*args, **kwargs)
            print('end')
            return result
    
        return wrapper
    
    
    def add_num(a, b):
        return a + b
    
    
    # 첫번째 사용 방법
    f = print_info(add_num)
    r = f(1, 2)
    print(r)
    
    '''
    start
    end
    3
    '''
    
    
    # 두번째 사용 방법
    @print_info
    def add_num_deco(a, b):
        return a + b
    
    
    r = add_num_deco(1, 2)
    print(r)
    
    
    ####################################################################
    
    def deco_1(func):
        def wrapper(*args, **kwargs):
            print('1-START')
            result = func(*args, **kwargs)
            print('1-END')
            return result
    
        return wrapper
    
    
    def deco_2(func):
        def wrapper(*args, **kwargs):
            print('2-START')
            result = func(*args, **kwargs)
            print('2-END')
            return result
    
        return wrapper
    
    
    # @deco_1 { deco_2 ( deco_test ) } 로 실행된다고 생각하면 될 듯?
    @deco_1
    @deco_2
    def deco_test(a, b):
        return a + b
    
    
    r = deco_test(1, 2)
    print(r)
    
    '''
    1-START
    2-START
    2-END
    1-END
    3
    '''

     

    Python Clousure 에 나오는 functools.partial() 을 이용하면 아래처럼도 작성할 수 있다.

    import functools
    
    
    def add_num(a, b):
        return a + b
    
    
    def print_info(f):
        print('start')
        result = f()
        print('end')
        return result
    
    
    if __name__ == '__main__':
        f = functools.partial(add_num, 1, 2)
        r = print_info(f)
        print(r)

     

    =====================================================================================

     

    class 의 __enter__(), __exit__() 를 이용할 수 있다.

     

    class CustomOpen(object):
        def __init__(self, filename):
            self.file = open(filename)
    
        def __enter__(self):
            return self.file
    
        def __exit__(self, ctx_type, ctx_value, ctx_traceback):
            self.file.close()
    
    with CustomOpen('file') as f:
        contents = f.read()

     

     

    =====================================================================================

     

     

    contextlib.contextmanager  + yield 를 이용해 작성할 수도 있다.

    import contextlib
    
    
    @contextlib.contextmanager
    def print_info(pre, post):
        print(pre)
        yield
        print(post)
    
    
    @print_info("start", "end")
    def add_num(a, b):
        return a + b
    
    
    if __name__ == '__main__':
        r = add_num(1, 2)
        print(r)

     

    위의 코드는 with 문으로 작성될 수 있다.

    import contextlib
    
    
    @contextlib.contextmanager
    def print_info(pre, post):
        print(pre)
        yield
        print(post)
    
    
    def add_num(a, b):
        return a + b
    
    
    if __name__ == '__main__':
        with print_info("start", "end"):
            r = add_num(1, 2)
        print(r)

     

    참고 코드

    import contextlib
    
    @contextlib.contextmanager
    def open_file(name):
        f = open(name, 'wb')
        yield f
        f.close()
        
    with open_file('some_file') as f:
        f.wirte('Hola')

     

    https://github.com/gto76/python-cheatsheet#context-manager 참고

    class MyOpen:
        def __init__(self, filename):
            self.filename = filename
        def __enter__(self):
            self.file = open(self.filename)
            return self.file
        def __exit__(self, exc_type, exception, traceback):
            self.file.close()
    
    with open('test.txt', 'w') as file:
        file.write('Hello World!')
            
    with MyOpen('test.txt') as file:
        print(file.read())

    'python > 기본' 카테고리의 다른 글

    Generator  (0) 2022.04.29
    Lambda  (0) 2022.04.29
    Closure  (0) 2022.04.29
    Function, kwargs  (0) 2022.04.29
    range, enumerate, zip  (0) 2022.04.29

    댓글

Designed by Tistory.