The module bytecodehack.closure allows the binding of a global reference in a function to a constant reference. It is similar to, but less general than, the attr_freeze module. It has a cuter interface, though.
A toy example:
from bytecodehacks.closure import bind_locals
def make_adder(n):
def adder(x):
return x+n
return bind_locals(adder)
Then "make_adder(2)" returns a monadic function that adds 2 to its argument. This can be used to implement parameterized callbacks without using the dreaded `default argument hack' or wrapping the callback in a typing intensive and slow class method.
A more imaginative use is to bind in a mutable object; then state is preserved across calls. This contradicts what the language reference says about code objects, so it's a bit smelly. Never mind, it works (for now). An example, which will be familiar if you have read ``Structure and Interpretation of Computer Programs,'' is:
def make_balance(initial_amount):
def withdraw(amount):
if current[0]<amount:
raise "debt!"
else:
current[0]=current[0]-amount
return current[0]
return bind(withdraw,current=[initial_amount])
This can be used as follows:
>>> from bytecodehacks.closure import make_balance
>>> W=make_balance(20)
>>> W(10)
10
>>> W(4)
6
>>> W(7)
Traceback (innermost last):
File "<stdin>", line 1, in ?
File "/home/mwh21/src/python/bytecodehacks/closure.py", line 98, in withdraw
raise "debt!"
debt!
>>> W(2)
4
Cool, huh?
Send comments to mwh@python.net