def outer_function(outer_variable): # 외부 함수
def inner_function(inner_variable): # 내부 함수
return outer_variable + inner_variable
return inner_function #내부 함수를 반환
# 클로저 생성
closure = outer_function(10) # outer_function의 반환 값은 inner_function
# 클로저 호출
result = closure(5)
print(result) #15
outer_function
이 실행되면 inner_function
이 반환된다.inner_function
은 outer_variable
을 기억하고 있다.inner_function
을 참조하게 되며, outer_function
의 outer_variable
값을 기억하고 있다.inner_function
이 outer_variable
(값 10)과 inner_variable
(값 5)을 합산하여 결과를 반환한다.outer_function
이 종료되었음에도 불구하고 closure는 outer_variable
값을 기억하는 클로저로 동작한다.[1] 상태 유지
[2] 데이터 은닉
[3] 함수형 프로그래밍 패러다임
def make_multiplier(factor):
def multiplier(number):
return number * factor
return multiplier
# 팩토리 함수 사용
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
make_multiplier
는 인자 factor
를 받아서, multiplier
라는 내부 함수를 반환한다.double
과 triple
은 각각 make_multiplier
에서 반환된 함수이다.double(5)
는 2를 곱한 결과인 10을, triple(5)
는 3을 곱한 결과인 15를 반환한다. 이때 double
과 triple
은 각각 다른 환경을 기억하는 클로저이다.def password_manager(correct_password):
#상태 저장 함수
_password = correct_password
def check_password(input_password):
if input_password == _password:
return "Access granted"
else:
return "Access denied"
return check_password
# 클로저 생성
password_checker = password_manager("my_secure_password")
# 비밀번호 입력
print(password_checker("wrong_password"))
print(password_checker("my_secure_password"))
password_manager
함수는 correct_password
를 받아 비밀번호를 저장하는 클로저를 반환한다.
이때 _password
는 외부에서 직접 접근할 수 없고, 내부 함수 check_password
만 _password
에 접근할 수 있다.
password_checker
는 클로저로, 내부적으로 비밀번호를 저장하고 사용자가 입력한 비밀번호를 검증하는 역할을 한다.
상태 유지: password_checker
는 비밀번호 상태를 기억하고, 외부에서는 이를 변경할 수 없다.
데이터 은닉: _password
는 클로저 내에서만 접근 가능하고 외부에서는 직접적으로 변경할 수 없다.
장점
password_checker
는 비밀번호를 검증하는 기능만 제공하고, 비밀번호 자체는 클로저 외부에서 보지 못한다.deposit
과 withdraw
메서드를 통해서만 잔액을 변경한다)def bank_account(initial_balance):
balance= initial_balance
def deposit(amount):
nonlocal balance
if amount > 0:
balance += amount
return f"Deposited {amount}. New balance: {balance}"
else:
return "Deposit amount must be positive"
def withdraw(amount):
nonlocal balance
if amount >0 and amount <= balance:
balance -= amount
return f"Withdrew {amount}. New balance: {balance}"
elif amount > balance:
return "Insufficient funds"
else:
return "Withdrawal amount must be positive"
def get_balance():
return f"Current balance: {balance}"
return deposit, withdraw, get_balance
#은행 계좌 생성
deposit, withdraw, get_balance = bank_account(1000)
print(deposit(500))
print(withdraw(200))
print(get_balance())
# 잘못된 입금/출금
print(deposit(-100))
print(withdraw(2000))
bank_account
는 초기 잔액을 설정하고, 잔액 상태를 관리하는 클로저를 반환한다. 클로저는 deposit
, withdraw
, get_balance
메서드를 제공하며, 잔액은 외부에서 접근할 수 없다.
nonlocal balance
를 사용하여 내부 함수에서 balance
값을 수정할 수 있다.
상태 유지: 계좌의 잔액이 계속해서 업데이트되고, 클로저 외부에서는 잔액을 변경할 수 없다.
데이터 은닉: balance
는 외부에서 직접 접근할 수 없고, deposit
, withdraw
, get_balance
를 통해서만 수정하거나 조회할 수 있다.
위 나오는 nonlocal에 대한 개념은 아래 링크 참고.
https://velog.io/@heyggun/python-nonlocal