티스토리 뷰

1. 클로저 (Closure)

- 함수와 그 함수가 참조하는 외부 변수(또는 자유 변수) 사이의 관계
- 클로저는 함수의 내부에서 정의된 함수로, 내부 함수가 외부 함수의 변수에 접근할 수 있고, 외부 함수는 내부 함수를 반환할 수 있음
- 함수와 그 함수가 참조하는 상태(변수)를 함께 저장하고 유지할 수 있음

# 2곱셈을 하고 싶을 때
def mul2(n):
  return n*2
print(mul2(5))

# 5곱셈을 하고 싶을 때
def mul5(n):
  return n*5
print(mul5(10))
 
 ## 더 발전을 시켜서
# __call__ : 곱셈에 대한 내용을 call에 넣음, 곱해지는 결과는 같음,
class Mul:
  def __init__(self, m):
    print('생성자 호출')
    self.m = m
  def __call__(self, n):
    print('call 호출')
    return self.m * n

 

이렇게 함수를 쓰면 쓸수록 메모리가 계속 올라감
곱하기 기능을 숫자별로 만들지 않고 class를 이용해서 객체를 생성하기

class Mul:
  def __init__(self, m):
    self.m = m
  def mul(self, n):
    return self.m * n

mul2 = Mul(2)          # 2의 곱셈
print(mul2.mul(10))
mul5 = Mul(5)
print(mul5.mul(10))    # 5의 곱셉


장점 : 객체를 만들고 그때 그때마다 원하는 숫자를 넣어줄 수 있음
단점 : 곱하는 수를 바꿀 때마다 객체를 만들어야 함

 

여기서 __call__ 을 사용해 더 발전시킴

class Mul:
  def __init__(self, m):
    print('생성자 호출')
    self.m = m
  def __call__(self, n):
    print('call 호출')
    return self.m * n

mul2 = Mul(2)
print(mul2(10))   # 원래라면 mul2.mul(10)
print(mul2(5))    # 코드가 좀 더 짧아짐

mul2라는 객체에 메서드를 부르지 않고 바로 실행 (이때 자동으로 호출되는 것이 call)

객체로 만든 것을 함수처럼 쓸 수 있음

 

클로저의 형태

def mul(m):
  def wrapper(n):
    return m * n
  return wrapper
 
mul2 = mul(2)
  # def wrapper(n):
  #   return 2 * n
print(mul2(10))        # 20

dan9 = mul(9)     # 9의 곱셈을 하고 싶다
print(dan9(5))

 

2. 데코레이터 (Decorator)

- 함수나 메서드의 동작을 수정하거나 확장하기 위한 강력한 도구

- 함수나 메서드를 래핑하거나 감싸서 추가 기능을 제공하며, 코드 재사용성과 가독성을 향상시킴

- @ 기호를 사용하여 함수나 메서드 위에 적용

import time

# 현재시간이 아니라 프로그램이 동작하는 사이 시간 구하기
# 시간의 흐름을 알고 싶을 때

# func1 : 덧셈
def func1(a, b):
  start = time.time()        # mil sec으로 숫자가 올라감, 1970년 1월1일 기준으로 올라가고 있음
  print('함수가 시작되었습니다')

  result = a + b

  end = time.time()
  print(f'함수 수행시간 {end - start}')
  return result

# func2 : 곱셈
  def func2(a, b):
  start = time.time()
  print('함수가 시작되었습니다')

  result = a * b

  end = time.time()
  print(f'함수 수행시간 {end - start}')
  return result

 

데코레이터의 만들기

# 덧셈, 곱셈 함수 만들기
def func1(a, b):
  result = a + b
  return result

def func2(a, b):
  result = a * b
  return result

 

두 함수의 공통점 : 시간 재는 것
어떤 함수에서든지 시간 재는 것을 붙여보고 싶다 -> 데코레이터

# 클로저 형태로 만들기
def elapsed(func):        # 곱셈이나 덧셈의 함수가 들어옴 (콜백함수처럼)
  def wrapper(a, b):
    start = time.time()
    print('함수가 시작되었습니다')

    result = func(a, b)

    end = time.time()
    print(f'함수 수행시간 {end - start}')
    return result
  return wrapper
  
deco1 = elapsed(func1)    # (클로저) wrapper가 리턴되는 것을 deco1에 넣음
result = deco1(10, 3)
print(result)

deco2 = elapsed(func2)    # (클로저) wrapper가 리턴되는 것을 deco2에 넣음
result = deco2(10, 3)
print(result)

 

 

# 외부함수 이름으로 데코레이터를 만들 수 있음
# 덧셈하는 함수롤 elapsed에 넣겠다
@elapsed
def func1(a, b):
  result = a + b
  return result

@elapsed
def func2(a, b):
  result = a * b
  return result

result = func1(10, 3)
print(result)
result2 = func2(10, 3)
print(result2)

# 클로저를 만들고 그 외부함수에 @붙이면 적용가능

 

 

 

 

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함