1.函数的引用
 
>>> def test():
    print('test:')

>>> test
<function test at 0x10ffad488>
>>> myfun=test
>>> myfun()
test:
>>>
 
函数名实际上指向函数体的内存区域,所以输出函数名时为:
<function test at 0x10ffad488>
 
若myfun=test,此时
 
 

变量 myfun 也指向了该内存区域,所以可以通过 test() 调用函数,也可以通过 myfun() 调用
这种情况,在C 、C++中类似 函数指针
 
2.什么是闭包?
在函数内部定义一个函数,并且这个函数用到外边函数的变量,这个函数以及用到的变量
统称为闭包
 
如:
 
>>> def test(number):
  print('---1---')
  def test_in():
    print(number+100)
    print('---2---')
  print('---3---')
  return test_in()

>>> test(2)
---1---
---3---
102
---2---
>>>
 
 
定义一个函数 test() ,在函数内部定义另一个函数 test_in()
test_in()又使用到了 外部函数 的变量,此时,test_in()和
被使用到的变量,统称为闭包
 
>>> def test(number):
    
    def test_in():   #2 只定义 「内」函数 没被执行
      print(number+100)
      print('---2---')
    
    return test_in()   #4 在return 语句,调用「内」函数
 
3.闭包的应用
 
如:
 
>>> def test(number):
    def test_in():
      print(number+100)
    return test_in

>>> ref=test(11)
>>> ref()
111
>>>
 
在 外部函数 内定义了 内部函数, 内部函数又使用了 内部函数的变量
外部函数返回了内部函数的地址:return test_in
此时 ref=test(11) ,使得ref得到了 test_in()的引用
于是可以通过 ref() 直接调用函数,虽然test_in使用了外部函数test()的变量number
但接下来每次调用ref() 都可以直接调用,外部函数变量number不被释放
 
>>> ref() # ref() 俨然如同一个独立函数了
111
>>> ref()
111
>>> ref()
111
>>>
 
4.外边函数被保留
 

外部函数虽然只调用了一次,但它不能被销毁,原因是内部函数还需要使用到它的变量,若该函数被销毁,则内边函数将无法被正常调用
ref() 之所以能够被反复调用,一方面在于调用外部函数test()时将test_in()的地址赋值给ref变量,这只让ref指向了函数体,能够以ref()的方式被调用,
而另一方面,当内部函数体被调用时,不能够出错,所以需要保留它需要用到的外部变量,因此number变量必须存在,test函数就必须保留。
 
闭包的一个特点:外部函数返回 内部函数的一个引用
 
5.闭包的一个应用实例:
 
>>> def test(a,b):
    def test_in(x):
      print(a*x+b)
  return test_in
'''
在调用test时,传递了a,b;实际上直线已经被确定,所以以下
line1和line2中直接传个值就可以了。
'''
>>> line1=test(2,5)
>>> line1(1)
7
>>> line2=test(3,4)
>>> line2(2)
10
>>>
在这个例子中,函数test_in和变量a,b构成闭包。
我们只需要通过变换a,b的值,就可以确定一条不同的直线(y=2x+5 / y=3x+4)
由此,闭包具备提高代码复用性的作用
如果没有闭包,我们需要每次创建直线函数时,同时说明a,b,x,这样需要更多的函数传递
而且减少了代码的可移植性:

>>> def line(a,b,x):
    print(a*x+b)

>>> line(1,1,1)
2
>>> line(2,2,2)
6
>>>
每次都需要传递a,b,x的值,而使用闭包的话,a,b可以只写一次,让调用过程简化
 
6.如图:重新开辟空间
 
 
 
Python解释器在处理闭包时,由于line1=test(1,1) 调用了test,此时test没有被释放,依然占用着内存;
在处理line2=test(2,2)时,不会覆盖到原先执行line1=test(1,1)时test的内存,也就是说不会改变
原先a=1,b=1的test,而是会新申请一块内存,执行「新」test,再保存a=2,b=2
 
7.闭包的思考
1.优化了变量
2.由于闭包引用了外部函数的变量,外部函数的局部变量没有被及时释放,消耗内存。
 
 
 

Python核心编程 | 浅谈闭包的使用的更多相关文章

  1. Python核心编程-闭包

    百度搜了一下闭包的概念:简而言之,闭包的作用就是在外部函数执行完并返回后,闭包使得收机制不会收回函数所占用的资源,因为内部函数的执行需要依赖外函数中的变量.这是对闭包作用的非常直白的描述,不专业也不严 ...

  2. Python核心编程的四大神兽:迭代器、生成器、闭包以及装饰器

      生成器 生成器是生成一个值的特殊函数,它具有这样的特点:第一次执行该函数时,先从头按顺序执行,在碰到yield关键字时该函数会暂停执行该函数后续的代码,并且返回一个值:在下一次调用该函数执行时,程 ...

  3. Python核心编程第二版(中文).pdf 目录整理

    python核心编程目录 Chapter1:欢迎来到python世界!-页码:7 1.1什么是python 1.2起源  :罗萨姆1989底创建python 1.3特点 1.3.1高级 1.3.2面向 ...

  4. Python核心编程(第二版)PDF

    Python核心编程(第二版) 目录 第1部分 Python核心第1章 欢迎来到Python世界1.1 什么是Python1.2 起源1.3 特点1.3.1 高级1.3.2 面向对象1.3.3 可升级 ...

  5. python核心编程第二版笔记

    python核心编程第二版笔记由网友提供:open168 python核心编程--笔记(很详细,建议收藏) 解释器options:1.1 –d   提供调试输出1.2 –O   生成优化的字节码(生成 ...

  6. python核心编程--笔记

    python核心编程--笔记 的解释器options: 1.1 –d   提供调试输出 1.2 –O   生成优化的字节码(生成.pyo文件) 1.3 –S   不导入site模块以在启动时查找pyt ...

  7. python核心编程--笔记(不定时跟新)(转)

    的解释器options: 1.1 –d   提供调试输出 1.2 –O   生成优化的字节码(生成.pyo文件) 1.3 –S   不导入site模块以在启动时查找python路径 1.4 –v   ...

  8. python核心编程笔记(转)

    解释器options: 1.1 –d   提供调试输出 1.2 –O   生成优化的字节码(生成.pyo文件) 1.3 –S   不导入site模块以在启动时查找python路径 1.4 –v   冗 ...

  9. 拒绝从入门到放弃_《Python 核心编程 (第二版)》必读目录

    目录 目录 关于这本书 必看知识点 最后 关于这本书 <Python 核心编程 (第二版)>是一本 Python 编程的入门书,分为 Python 核心(其实并不核心,应该叫基础) 和 高 ...

随机推荐

  1. Egret中使用P2物理引擎

    游戏中的对象按照物理规律移动,体现重力.引力.反作用力.加速度等物体特性,实现自由落体.摇摆运动.抛物线运动,以及物理碰撞现象的模拟.用于模拟物理碰撞.物理运动的引擎称为物理引擎. 来自瑞典斯德哥尔摩 ...

  2. nc 画界面,触发效果(第一种)

    package nc.ui.hzctr.sellctr.action; import java.awt.BorderLayout; import java.awt.Dimension; import ...

  3. python_day12_html

    目录: 简单web的服务器代码 html简介 html常用标签 一.简单web的服务器代码 1.简单python服务器代码: import socket def main(): sock = sock ...

  4. 64位版本为什么叫amd64,而不是intel64

    64位版本为什么叫amd64,而不是intel64? 首先了解下常见的几个架构: X86是一个指令集,是刚有个人电脑时候的什么8086,286,386的那个兼容的指令集.   “x86-64”,有时会 ...

  5. 74.CocoaPods安装和使用教程

    CocoaPods安装和使用教程  Code4App 原创文章.转载请注明出处:http://code4app.com/article/cocoapods-install-usage 第一: Coco ...

  6. tomcat 配置 使用 HTTPS

    1.生成证书 keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "d:\temp ...

  7. 20155339 Exp9 Web安全基础

    Exp9 Web安全基础 基础问题回答 (1)SQL注入攻击原理,如何防御 原理:它是利用现有应用程序,将恶意的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入恶意SQL语句得到 ...

  8. Alpha冲刺 - (4/10)

    Alpha冲刺 - (4/10)   Part.1 开篇 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Part.2 成员汇报 组员1(组长)柯奇豪 过去两天完成了哪些任务 ...

  9. 使用pyinstaller打包python小程序(没有使用第三方模块)

    准备: 1,xxx.py程序文件 2,自定义的图标文件:xxx.ico 图标文件应该包含常见的多分辨率格式,以便适应在不同场合显示,不能是单一图片. 你可以用专用的软件处理生成图标,不过少量的图标生产 ...

  10. vuejs-devtools

    先看看http://www.cnblogs.com/zhnaglei/p/7121482.html 这里的方法. 如果出现vue.js not detected之类的错误.试试用调试模式,就是用npm ...