Created
July 7, 2015 16:15
-
-
Save etscrivner/3abbe104079eec42ae0e to your computer and use it in GitHub Desktop.
Simple python closure objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Simple message-passing closure objects example similar to SICP 3.1.1 | |
""" | |
def make_account(balance): | |
# In Python 2.x we have to close over a mutable variable, so we are using | |
# obj.__setitem__(...) assignment rather than regular assignment which | |
# attempts to create a new variable within the current scope when each | |
# closure is initially compiled. Otherwise cannot assign the balance value | |
# with our deposit and withdraw closures. | |
# In Python 3.x we can use the `nonlocal` keyword (with usage similar to | |
# `global`) within our closures instead. | |
current_balance = [balance] | |
def deposit(amount): | |
current_balance[0] = current_balance[0] + amount | |
return current_balance[0] | |
def withdraw(amount): | |
if current_balance[0] >= amount: | |
current_balance[0] = current_balance[0] - amount | |
return current_balance[0] | |
return 'Insufficient funds' | |
def dispatch(method_name): | |
if method_name == 'deposit': | |
return deposit | |
elif method_name == 'withdraw': | |
return withdraw | |
elif method_name == 'balance': | |
return current_balance[0] | |
else: | |
raise ValueError('Unknown request -- {}'.format(method_name)) | |
return dispatch | |
account = make_account(100) | |
account("deposit")(25) | |
account("withdraw")(50) | |
print account("balance") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment