Python의 클로저, 데코레이터에 대해 알아봅니다.
def mul3(n):
return n * 3
def mul5(n):
return n * 5
class Mul:
def __init__(self, m):
self.m = m
def mul(self, n):
return self.m * n
if __name__ == "__main__":
mul3 = Mul(3)
mul5 = Mul(5)
print(mul3.mul(10)) # 30 출력
print(mul5.mul(10)) # 50 출력
__call__ 메서드를 이용하여 개선__call__로 바꾸었다. __call__ 함수는 Mul 클래스로 만든 객체에 인수를 전달하여 바로 호출할 수 있도록 하는 메서드.class Mul:
def __init__(self, m):
self.m = m
def __call__(self, n):
return self.m * n
if __name__ == "__main__":
mul3 = Mul(3)
mul5 = Mul(5)
print(mul3(10)) # 30 출력
print(mul5(10)) # 50 출력
def mul(m):
def wrapper(n):
return m * n
return wrapper
if __name__ == "__main__":
mul3 = mul(3)
mul5 = mul(5)
print(mul3(10)) # 30 출력
print(mul5(10)) # 50 출력
def myfunc():
print("함수가 실행됩니다.")
import time
def myfunc():
start = time.time()
print("함수가 실행됩니다.")
end = time.time()
print("함수 수행시간: %f 초" % (end-start))
myfunc()
decorated_myfunc = elapsed(myfunc)로 생성한 decorated_myfunc를 decorated_myfunc()로 실행하면 실제로는 elapsed 함수 내부의 wrapper 함수가 실행되고, 이 함수는 전달받은 myfunc 함수를 실행하면서 실행 시간을 함께 출력한다.import time
def elapsed(original_func): # 기존 함수를 인수로 받는다.
def wrapper():
start = time.time()
result = original_func() # 기존 함수를 수행한다.
end = time.time()
print("함수 수행시간: %f 초" % (end - start)) # 기존 함수의 수행시간을 출력한다.
return result # 기존 함수의 수행 결과를 반환한다.
return wrapper
def myfunc():
print("함수가 실행됩니다.")
decorated_myfunc = elapsed(myfunc)
decorated_myfunc()
@+함수명이 있으면 데코레이터 함수로 인식한다. @elapsed(@+함수명)라는 데코레이터를 추가.import time
def elapsed(original_func): # 기존 함수를 인수로 받는다.
def wrapper():
start = time.time()
result = original_func() # 기존 함수를 수행한다.
end = time.time()
print("함수 수행시간: %f 초" % (end - start)) # 기존 함수의 수행시간을 출력한다.
return result # 기존 함수의 수행 결과를 반환한다.
return wrapper
@elapsed
def myfunc():
print("함수가 실행됩니다.")
# decorated_myfunc = elapsed(myfunc) # @elapsed 데코레이터로 인해 더이상 필요하지 않다.
# decorated_myfunc()
myfunc()
*args와 **kwargs 매개변수를 이용하면 된다.import time
def elapsed(original_func): # 기존 함수를 인수로 받는다.
def wrapper(*args, **kwargs): # *args, **kwargs 매개변수 추가
start = time.time()
result = original_func(*args, **kwargs) # 전달받은 *args, **kwargs를 입력파라미터로 기존함수 수행
end = time.time()
print("함수 수행시간: %f 초" % (end - start)) # 수행시간을 출력한다.
return result # 함수의 결과를 반환한다.
return wrapper
@elapsed
def myfunc(msg):
""" 데코레이터 확인 함수 """
print("'%s'을 출력합니다." % msg)
myfunc("You need python")
+) *args와 **kwargs
*args: 모든 입력 인수를 튜플로 변환하는 매개변수.
**kwargs: 모든 ‘키=값’ 형태의 입력 인수를 딕셔너리로 변환하는 매개변수.
func(1, 2, 3, name='foo', age=3) 함수가 입력 인수의 개수와 형태에 상관없이 모든 입력을 처리하려면.
def func(*args, **kwargs):
print(args)
print(kwargs)
func(1, 2, 3, name='foo', age=3)
# (1, 2, 3)
# {'age': 3, 'name': 'foo'}
*args, **kwargs 매개변수를 지정하면 다양한 입력 인수를 모두 처리할 수 있다.