Remembering the context

Chris Rebert clp2 at rebertia.com
Wed Apr 28 04:44:23 EDT 2010


On Wed, Apr 28, 2010 at 1:31 AM, GZ <zyzhu2000 at gmail.com> wrote:
> I am looking at the following code:
>
> def fn():
>
>    def inner(x):
>         return tbl[x]
>
>    tbl={1:'A', 2:'B'}
>    f1 = inner   # I want to make a frozen copy of the values of tbl
> in f1
>    tbl={1:'C', 2:'D'}
>    f2 = inner
>   return (f1,f2)
>
> f1,f2 = fn()
> f1(1)  # output C
> f2(1) # output C
>
> What I want is for f1 to make a frozen copy of tbl at the time f1 is
> made and f2 to make another frozen copy of tbl at the time f2 is made.
> In other words, I want f1(1)=='A' and f2(1)=='C'.
>
> One way to do this is to use functools.partial
>
> def fn():
>
>    def inner(tbl, x):
>         return tbl[x]
>
>    tbl={1:'A', 2:'B'}
>    f1 = functools.partial(inner,tbl)   # I want to make a frozen copy
> of the values of tbl in f1
>    tbl={1:'C', 2:'D'}
>    f2 = functools.partial(inner,tbl)
>   return (f1,f2)
>
> I am wondering if there is any other way to do this.

I prefer the functools.partial() method personally, but the other
obvious way to go about it is:

def fn():
    tbl={1:'A', 2:'B'}
    f1 = lambda x, table=tbl: table[x]

    tbl={1:'C', 2:'D'}
    f2 = lambda x, table=tbl: table[x] # we have to be repetitive

    return (f1,f2)

Note that default argument values are evaluated exactly once, at
definition-time.
The lambdas can equivalently be replaced with def-s of course.

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list