Scope of lambda functions and their parameters?

后端 未结 10 1073
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 13:22

I need a callback function that is almost exactly the same for a series of gui events. The function will behave slightly differently depending on which event has called it.

10条回答
  •  没有蜡笔的小新
    2020-11-22 13:41

    Python does uses references of course, but it does not matter in this context.

    When you define a lambda (or a function, since this is the exact same behavior), it does not evaluate the lambda expression before runtime:

    # defining that function is perfectly fine
    def broken():
        print undefined_var
    
    broken() # but calling it will raise a NameError
    

    Even more surprising than your lambda example:

    i = 'bar'
    def foo():
        print i
    
    foo() # bar
    
    i = 'banana'
    
    foo() # you would expect 'bar' here? well it prints 'banana'
    

    In short, think dynamic: nothing is evaluated before interpretation, that's why your code uses the latest value of m.

    When it looks for m in the lambda execution, m is taken from the topmost scope, which means that, as others pointed out; you can circumvent that problem by adding another scope:

    def factory(x):
        return lambda: callback(x)
    
    for m in ('do', 're', 'mi'):
        funcList.append(factory(m))
    

    Here, when the lambda is called, it looks in the lambda' definition scope for a x. This x is a local variable defined in factory's body. Because of this, the value used on lambda execution will be the value that was passed as a parameter during the call to factory. And doremi!

    As a note, I could have defined factory as factory(m) [replace x by m], the behavior is the same. I used a different name for clarity :)

    You might find that Andrej Bauer got similar lambda problems. What's interesting on that blog is the comments, where you'll learn more about python closure :)

提交回复
热议问题