<aside> 💡 클로저(Closure)는 둘러싼 스코프의 변수값을 기억하는 함수입니다. 값을 은닉하거나 고차함수를 생성하는데 사용됩니다.

</aside>

def make_counter():
    count = 0 # 반환될 함수에 의해 기억될 값

    def counter():
        nonlocal count # 💡 쉐도잉하지 않도록
        count += 1
        return count
    return counter

counter_1 = make_counter()

for _ in range(5):
    print(counter_1())

count_now = counter_1()

pass
# 새로 만든 카운터는 별개의 값들 반환
counter_2 = make_counter()
c2_counts = [counter_2() for i in range(10)]
# 매개변수를 기억하는 내부함수

def make_multiplier_of(n):
    def multiplier(x):
        return x * n
    return multiplier

times3 = make_multiplier_of(3)
times5 = make_multiplier_of(5)

mults = [(times3(i), times5(i)) for i in range(1, 10)]

pass
def make_secure_access(data):
    def secure_access(key):
        if key == 'abcd1234':
            return data
        else:
            return "⚠️ 비밀번호 오류"
    return secure_access

access_data = make_secure_access("🎁 기밀정보")

try_1 = access_data("1234abcd")
try_2 = access_data("abcd1234")

pass
# 💡 데코레이터에서 이미 사용한 바 있음
def my_decorator(func):
    def wrapper():
        print("함수 실행 전")
        func()
        print("함수 실행 후")
    return wrapper #4.

@my_decorator
def say_hello():
    print("안녕하세요!")

say_hello()