zoukankan      html  css  js  c++  java
  • 作用域与带有循环变量的默认参数相比较问题

    这个问题是来自于美国作家 鲁特兹(Mark Lutz)所作的一本《Learning Python,Fourth Edition》书里提及到的。

    原文翻译如下:

    如果 lambda 或者 def 在函数中定义,嵌套在一个循环之中,并且嵌套的函数引用了一个上层作用域的变量,该变量被循环变量所改变,所有在这个循环变量中产生的函数将会有相同的值——在最后一次循环中完成时被引用变量的值。

    我们来看下一个例子:

    >>> def makeActions():
    ...     acts = []
    ...     for i in range(5):
    ...             acts.append(lambda x: i ** x)
    ...     return acts
    ... 
    >>> acts = makeActions()
    >>> acts[0](2)
    16
    >>> acts[1](2)
    16
    >>> acts[2](2)
    16
    >>> acts[3](2)
    16
    >>> acts[4](2)
    16 

    批注这个例子试图在创建一个函数的列表,其中每个函数都记住嵌套作用域中当前变量 i 的值。但是这并不怎么有效:因为嵌套作用域中的变量在嵌套的函数被调用时才进行查找,所以它们实际上记住的是同样的值(在最后一次循环迭代中循环变量的值)

    我们来看下另一个例子:

    >>> def makeActions():
    ...     acts = []
    ...     for i in range(5):
    ...             acts.append(lambda x, i = i: i ** x)
    ...     return acts
    ... 
    >>> acts = makeActions()
    >>> acts[0](2)
    0
    >>> acts[1](2)
    1
    >>> acts[2](2)
    4
    >>> acts[3](2)
    9
    >>> acts[4](2)
    16

    批注这个是在嵌套作用域的值和默认参数方面遗留的一种仍需要解释清楚的情况,而不是引用所在的嵌套作用域的值。为了实现你想要的效果,则必须使用默认参数把当前的值传递给嵌套作用域的变量。因为默认参数是在嵌套函数所创建时评估的(而不是在其稍后调用时),每一个函数记住了自己的变量 i 的值

    你也可以将上述代码所定义的函数等价于:

    >>> def makeActions():
    ...     acts = []
    ...     for i in range(5):
    ...             def func(x):
    ...                     return i ** x
    ...             acts.append(func(x))
    ...     return acts
    ... 

    >>> def makeActions():
    ...     acts = []
    ...     for i in range(5):
    ...             def func(x, i = i):
    ...                     return i ** x
    ...             acts.append(func(x, i))
    ...     return acts
    ... 
    

    批注:这是一种相当隐晦的情况,但是它会在实际情况中发生,特别是在生成应用于 GUI 一些部件的回调处理函数代码中(例如,按钮的事件处理)。

  • 相关阅读:
    Android内存优化5 了解java GC 垃圾回收机制3
    一起刑事案件法庭辩护 z
    辩护技巧总结——律师在刑事辩护中应注意的几个问题 z
    证据对抗、证据链标准 z
    里德九步审讯法 z
    WCF服务在高并发情况下报目标积极拒绝的异常处理 z
    C#EasyHook例子C# Hook 指定进程C#注入指定进程 z
    玄机论坛Socket类库源码 当前版本 2.6.3 更新日期:10-09/2015 z
    庭审全程文字实录 z
    庭审精彩语录整理 z
  • 原文地址:https://www.cnblogs.com/importthis/p/8975690.html
Copyright © 2011-2022 走看看