python 函数闭包,python闭包的条件

  python 函数闭包,python闭包的条件

  本文主要介绍Python函数中闭包和延迟绑定的细节。文章围绕主题,详细介绍了细节,具有一定的参考价值。有需要的朋友可以参考一下。

  闭包必须满足以下3个条件:

  必须有嵌入的函数。嵌入式函数必须应用外部函数的变量。外部函数的返回值必须是嵌入式函数关于请看下面代码:.

  定义乘数():

  return[lambda x : I * x for I in range(4)]

  print([m(2)for m in multipliers()])

  [6, 6, 6, 6]

  为什么输出结果是[6,6,6,6]?这段代码相当于

  定义乘数():

  funcs=[]

  对于范围(4):中的I

  定义栏(x):

  返回x*i

  函数追加(条形)

  返回函数

  print([m(2)for m in multipliers()])

  [6, 6, 6, 6]

  当代码运行时,解释器遇到一个列表解析,并在一个循环中从multipliers()函数获取值,而multipliers()函数返回一个包含四个元素的列表对象。

  每个元素都是一个匿名函数(其实四个匿名函数并不完全准确。实际上它们是四个匿名函数的计算值,因为I的后续循环不仅循环了四次,

  同时也提供了I的变量引用。四个周期后,I指向值i=3。这时匿名函数开始引用i=3并计算结果。所以会有[6,6,6,6],

  因为匿名函数中的I在下面的循环中并不会立即引用I的值,而是只有在嵌套函数运行时才会找到I的值,这个特性就是延迟绑定)

  #为了便于理解,你可以把乘法器的内部想象成这样(这个是伪代码,不准确):

  定义乘数():

  return[x : 3 * x,x : 3 * x,x : 3 * x,x : 3 * x]

  因为Python解释器,在遇到lambda(类似于def)时,只是定义一个匿名的函数对象,保存在内存中。只有当这个匿名函数被调用时,

  将运行内部表达式,而对于范围(4)中的I是另一个表达式。在开始运行lambda函数之前,必须等到这个表达式结束。此时,I指向3,X指向2。

  改进

  定义乘数():

  #添加了默认参数i=i。

  return [lambda x,i=i: i*x for i in range(4)]

  print([m(2)for m in multipliers()])

  [0, 2, 4, 6]

  相当于:

  定义乘数():

  funcs=[]

  对于范围(4):中的I

  def bar(x,i=i):

  返回x * i

  函数追加(条形)

  返回函数

  print([m(2)for m in multipliers()])

  [0, 2, 4, 6]

  添加一个i=i后,匿名函数会添加一个默认参数,python函数中的默认参数,

  当python解释器遇到def(i=i)或lambda关键字时,必须初始化默认参数。

  此时,对于range(4)中的I,匿名函数的默认参数I,每次循环都需要找到对I的引用。

  当i=0时,第一个匿名函数的默认参数值为0;当i=1时,第二个匿名函数的默认参数值为1,依此类推。

  #为了便于理解,你可以把乘法器的内部想象成这样(这个是伪代码只是为了理解):

  定义乘数():

  返回[lambda x,i=0: i*x,lambda x,i=1: i*x,lambda x,i=2: i*x,lambda x,i=3:i*x i=3]

  # x的引用是2,所以输出的结果是:[0,2,4,6]

  当然你的i=i也可以改成A=I。

  定义乘数():

  #添加了默认参数A=I。

  return [lambda x,a=i: x*a for i in range(4)]

  print([m(2)for m in multipliers()])

  [0, 2, 4, 6]

  Python的延迟绑定实际上只在嵌套函数运行时引用外部变量I。不运行时,不寻找I的值,这就是第一个函数输出结果为[6,6,6,6]的原因。

  关于Python函数中闭包和延迟绑定的细节,本文到此结束。有关Python延迟绑定的更多信息,请搜索流行的IT软件开发工作室以前的文章,或者继续浏览下面的相关文章。希望大家以后多多支持盛行的IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: