开发者

In python, when you pass internally defined functions into other functions, how does it keep the variables?

开发者 https://www.devze.com 2023-03-28 16:13 出处:网络
For example, why does this work? def func1(func1var): def innerfunc(innerfuncvar): if func1var == 1: print innerfuncvar

For example, why does this work?

def func1(func1var):
    def innerfunc(innerfuncvar):
        if func1var == 1:
             print innerfuncvar
        else:
             print 5
    func2(innerfunc)


def func2(function):
     function(9)

When innerfunc is called in func2, how does it know the values o开发者_JAVA技巧f func1var?


You've created a closure. Basically, think of it like this, from the point of view of the inner function:

func1var = whatever

def func2(function):
    function(9)

def innerfunc(innerfuncvar):
    if func1var = 1:
         print innerfuncvar
    else:
         print 5

func2(innerfunc)

It doesn't care whether func1var is in an outer or global scope -- it just looks for it in each scope outward, starting with it's own local scope. It's just like when you reference a module global variable from inside a class or function in that module.


Python actually goes to some lengths to do this for you. When you define a function inside a function, you may use variables from the outer function in the inner function. This is true for any depth of nesting (that is, you can have a function inside a function inside a function inside a function... to any depth... and the innermost function can use variables from any of the enclosing functions). If there are conflicting names, the innermost variable with the name requested is used.

What's more, Python actually captures any variables you use from the outer function and stores them in the inner function, which is called a closure. So you can not only pass a function to another function, as you are doing, but you can return a function from a function, and variables you use from the outer function that were in effect when the function was defined will still be accessible from the returned function, even though the outer function isn't running any more. This is a fairly advanced feature, but it lets you do something like this:

def make_adder(increment):
    def adder(number):
        return number + increment
    adder.__name__ = "adder(%s)" % increment
    return adder

This function is a function that creates a function that adds the specified value to it. For example:

add1 = make_adder(1)
add5 = make_adder(5)

print add1(10)   # 11
print add5(10)   # 15

In this case, the value you pass to make_adder is captured and stored in the function that gets returned. This allows you to create a bunch of functions that add any number to their arguments. Which is a trivial example that isn't actually very useful in real life, but serves to illustrate the feature.


Each time you call func1(func1var), Python actually builds a new function innerfunc(). Since func1var is perfectly defined when innerfunc() is created, the code of the new innerfunc() function contains the correct value of func1var.

0

精彩评论

暂无评论...
验证码 换一张
取 消