-
Decorator / contextmanagerpython/기본 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