Thursday 13 September 2012

Python curries locals

I bloody love Python....

I needed to write some code that composes a command to modify port settings. Here's what it looked like:

def port_assign(io0="unchanged", io1="unchanged",
                io2="unchanged", io3="unchanged"):
    send("IO_ASSIGN "+" ".join([locals()["io%d"%v] for v in range(0,4)]))

so the idea is that
 port_assign()
is equivalent to
 send("IO_ASSIGN unchanged unchanged unchanged unchanged")
and
 port_assign(io2="pulldown")
is equivalent to
 send("IO_ASSIGN unchanged unchanged pulldown unchanged")

Cool.

Except it doesn't work. The problem is locals() is evaluated inside the iterator so it doesn't contain the parameters. The solution is to "curry" (partially evaluate in advance, forming a "closure") the call to locals() so that it picks up the right scope:


def port_assign(io0="unchanged", io1="unchanged",
                io2="unchanged", io3="unchanged"):
    params=locals()
    send("IO_ASSIGN "+" ".join([params["io%d"%v] for v in range(0,4)]))

1 comment: