python基础-闭包
def bibao():
li = []
n = [1]
def inner():
li.append(n[0])
n[0] +=1
print(li)
return inner b = bibao()
b()
b()
结果分别为[1]和[1,2]
1.简述
内部函数被当做对象返回时,夹带了这个内部函数之外的自由变量
闭包:带着当前变量环境的函数
b是inner函数,具有当前变量的值,li是一个空列表,n=[1]
b(),当b被调用时,li.append(1),n=[2],li=[1],这些变量都被存储在了__closure__中
b.__closure__返回值是一个列表,包含自由变量li和n的值
2.典型错误
def wrapper():
n = 1
def inner():
n += 1
print(n)
return inner
w = wrapper()
w()
w()
运行时会抛出异常
UnboundLocalError: local variable 'n' referenced before assignment
原因是n=n+1时将n变为局部变量,不再是inner函数外的自由变量,可以通过下面的例子证明
1.不在inner内部对n进行赋值时,n仍然为外部变量
def wrapper():
n = 1
def inner():
print(n)
return inner
w = wrapper()
w()
print(w.__closure__)
打印结果为:(<cell at 0x101dc92b8: int object at 0x100983c20>,)
证明此时是有外部变量的
2.在inner内部对n进行赋值时,n变为局部变量
def wrapper():
n = 1
def inner():
n = 1
print(n)
return inner
w = wrapper()
w()
print(w.__closure__)
打印结果为:None
证明此时n变为了局部变量
3.针对2中的错误,解决办法
使用 nonlocal将n的属性变为不是局部变量
def wrapper():
n = 1
def inner():
nonlocal n
n = n + 1
print(n)
return inner
w = wrapper()
w()
print(w.__closure__)
(<cell at 0x101dc92b8: int object at 0x100983c40>,)
打印结果中又有自由变量了
nonlocal表示n不是局部变量,不改变它的属性
4.注意
4.1 具体参考python官网:https://www.python.org/dev/peps/pep-3104/
4.2 如果在自由变量中未声明,直接在函数内部使用的nonlocal,会报错
def wrapper():
n = 1
def inner():
nonlocal n
n = n + 1
print(n)
m = 1
nonlocal m
return inner
w = wrapper()
w()
print(w.__closure__)
如上代码会报错
SyntaxError: name 'm' is assigned to before nonlocal declaration
m必须先是声明为自由变量
5.装饰器与@
pass
python基础-闭包的更多相关文章
- python基础--闭包and装饰器
闭包函数:函数内部定义的函数:引用了外部变量但非全局变量 装饰器:有了闭包的概念再去理解装饰器就会相对容易一些.python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加 ...
- python基础--闭包、装饰器
装饰器的详细使用 (1)小知识点补充 在这里我们先学一个简单的知识点. li = ['alex', '银角', '女神', 'egon', '太白'] for i in enumerate(li): ...
- python基础-闭包函数和装饰器
闭包函数和装饰器 闭包函数 概念:在函数中(嵌套)定义另一个函数时,内部函数引用了外层函数的名字. 特性 闭包函数必须在函数内部定义 闭包函数可引用外层函数的名字 闭包函数是函数嵌套.函数对象.名称空 ...
- python基础—函数嵌套与闭包
python基础-函数嵌套与闭包 1.名称空间与作用域 1 名称空间分为: 1 内置名称空间 内置在解释器中的名称 2 全局名称空间 顶头写的名称 3 局部名称空间 2 找一个名称的查找顺序: ...
- Python基础+Pythonweb+Python扩展+Python选修四大专题 超强麦子学院Python35G视频教程
[保持在百度网盘中的, 可以在观看,嘿嘿 内容有点多,要想下载, 回复后就可以查看下载地址,资源收集不易,请好好珍惜] 下载地址:http://www.fu83.cc/ 感觉文章好,可以小手一抖 -- ...
- python基础——返回函数
python基础——返回函数 函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_ ...
- Python基础:函数式编程
一.概述 Python是一门多范式的编程语言,它同时支持过程式.面向对象和函数式的编程范式.因此,在Python中提供了很多符合 函数式编程 风格的特性和工具. 以下是对 Python中的函数式编程 ...
- python基础教程
转自:http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html Python快速教程 作者:Vamei 出处:http://www.cn ...
- python基础—函数装饰器
python基础-函数装饰器 1.什么是装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...
随机推荐
- Ubuntu 14.04 更新 setuptools 至 19.2 版本
参考: Error: "No module named _markerlib" when installing some packages on virtualenv Ubuntu ...
- [原][工具][windows10安装][0x800F081F]windows 10 如何离线安装.net framework3.5 || 安装出现错误代码0x800F081F时如何解决
参考解决方案:https://zhidao.baidu.com/question/1896669183365806820.html?fr=iks&word=win10%B0%B2%D7%B0+ ...
- nodejs点滴
1.exports与module.exports http://cnodejs.org/topic/5231a630101e574521e45ef8 因为require指向了module.export ...
- guxh的python笔记三:装饰器
1,函数作用域 这种情况可以顺利执行: total = 0 def run(): print(total) 这种情况会报错: total = 0 def run(): print(total) tot ...
- Python自学:第二章 Python之禅
>>print import <Python之禅>,提姆·彼得斯著 美胜于丑. 显式优于隐式. 简单胜于复杂. 复杂总比复杂好. 平的比嵌套的好. 稀疏胜于稠密. 可读性计数. ...
- Lab 7-2
Analyze the malware found in the file Lab07-02.exe. Questions and Short Answers How does this progra ...
- selenium自动加载各个浏览器插件
在自动化测试过程中,通过selenium启动浏览器时,可能需要加载插件(如测试用的firebug.或产品中要求必须添加某插件等).读取用户数据(自己浏览器的配置文件/别人直接给的浏览器配置文件).设置 ...
- 『TensorFlow』读书笔记_SoftMax分类器
开坑之前 今年3.4月份的时候就买了这本书,同时还买了另外一本更为浅显的书,当时读不懂这本,所以一度以为这本书很一般,前些日子看见知乎有人推荐它,也就拿出来翻翻看,发现写的的确蛮好,只是稍微深一点,当 ...
- eslint详细配置
vue-cli3按照官网教程配置搭建后,发现每次编译,eslint都抛出错误, 修改配置在 .eslintrc.js中修改 或者 关闭eslint 1.关闭eslint 直接注释掉package ...
- RabittMQ安装和Erlang安装教程
安装Erlang 官方安装地址文档: http://www.rabbitmq.com/install-rpm.html 根据官网的推荐 进入到专为RabbitMQ整理的极简版Erlang https: ...