Understanding Python Closures
Question: I always thought that Python 2.7 functions refer to the scope they were
defined in. Consider the following code. Why is the second output not
_"calculating: sin"_?

Is there any way to modify the code so it is working as expected?

    
    
    import math
    
    mymath = dict()
    
    for fun in ["sin", "cos"]:
        def _impl(val):
            print "calculating: %s" % fun
            return getattr(math, fun)(val)
        mymath[fun] = _impl
    
    # calculating: cos
    print mymath["cos"](math.pi)
    
    # calculating: cos <- why?
    print mymath["sin"](math.pi)
    


Answer: The value of `fun` is evaluated when the function is called.

In the example you provided, `fun` is a global variable, and it's value is
"cos" after the `for` loop runs.

I think you expect the value of `fun` to be substituted when you create the
function, but it's not. The function evaluates the value of the variable when
it runs just like it's supposed to.

It's not about the namespace in which you define the function, but the
namespace in which you run the function.

    
    
    import math
    
    mymath = dict()
    
    for fun in ["sin", "cos"]:
        def _impl(val):
            print "calculating: %s" % fun
            return getattr(math, fun)(val)
        mymath[fun] = _impl
    
    
    fun = 'tan'
    # will print and calculate tan
    print mymath["cos"](math.pi)
    

