zoukankan      html  css  js  c++  java
  • 一段关于python 闭包的例子

    >>> def counter(a=0):
    ...     count = a
    ...     def incr():
    ...             b = 1 + count
    ...             return b
    ...     return incr
    ...
    >>> count = counter(5)
    >>> print count()
    6
    >>> print count()
    6
    >>>
    >>> def counter(start_at=0):
    ...     count = [start_at]
    ...     def incr():
    ...             count[0] += 1
    ...             return count[0]
    ...     return incr
    ...
    >>> count = counter(5)
    >>> print count()
    6
    >>> print count()
    7
    >>> print count()
    8
    >>>
    

      

    有若干疑点不懂。 列出来一一解惑

    1. 第二段代码的function counter 在内部定义了一个function incr。这个incr被当做返回值返回。 我们用count 去接受这个返回值然后每次调用的时候 print count() 会得到累加的结果6, 7 , 8. 但是这个累加值的变量应该是定义在counter()这个外层函数中的啊。 以我的理解外层函数结束了,其定义的变量应该也不可访问了。为什么count函数可以不断的访问并累加这个值呢? 

    这是因为python中对变量的访问都是引用。外层函数生成了一个变量,内层函数count又对这个变量引用了一次。只要内层函数对这个变量的引用还在,这个变量就不会被销毁,就仍然可用。 我所理解的外层函数退出,变量就不可以再访问其实是因为我潜意识里认为外层函数退出,变量的引用就结束了。然而在这个例子中变量的引用并没有结束,所以仍然存在并且可以访问。

    2. 对于第二段代码,我们知道它返回一个函数调用。那么也就是说counter()类似于一个函数名。而我们用counter()()就应该是这个函数调用。 我们看一下执行,

    >>> counter()()
    1
    >>> counter()()
    1
    

    确实是函数调用,但是为什么不是像print count()这种累加呢? 

    这是因为,counter()每次运行生成一个新的函数对象并返回。如下所示:

    >>> counter()
    <function incr at 0xe10c848>
    >>> counter()
    <function incr at 0xe10ca28>
    >>>

    所以 counter()()每次都相当于第一次执行。每次是在执行不同的函数instance。 而 count=counter() print count()这种方式则不然。 这种方式是执行一次counter()以后把返回的函数调用保存在一个变量也就是count中形成了一次引用。以后每次调用print count()都是对这同一个函数调用。

  • 相关阅读:
    js 判断中文输入法是否输入完成(系统自带输入法)
    Winform DataGridView中的Button点击事件
    利用sp_addlinkedserver实现远程数据库链接
    锐浪报表多个子报表赋值
    未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序
    C# 中解决页面刷新后字体等变大问题
    QRCode 扫描二维码、扫描条形码、相册获取图片后识别、生成带 Logo 二维码、支持微博微信 QQ 二维码扫描样式
    c#4.0 qrcode二维码生成 简单封装
    .net2.0 生成二维码
    c# 生成下部带文字的二维码
  • 原文地址:https://www.cnblogs.com/kramer/p/3671362.html
Copyright © 2011-2022 走看看