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函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...
随机推荐
- 阿里技术专家详解Dubbo实践,演进及未来规划
https://mp.weixin.qq.com/s/9rVGHYfeE8yM2qkSVd2yEQ
- Windows 用bat脚本带配置启动redis,并用vb脚本使其在后台运行。
最近,在Windows上用开发PHP程序,需要用到Redis,每天要打开一个运行redis-server.exe的窗口这样比较烦,因为窗口就一直打开着,不能关闭. 所以就想着通过写脚本的方式,让他在后 ...
- 线程(六)之LOCK和synchronized
在java.util.concurrent.locks包中有很多Lock的实现类,常用的有ReentrantLock.ReadWriteLock(实现类ReentrantReadWriteLock), ...
- hibernate 的API使用
1.Query对象:不需要写sql语句,但需要hql语句,和sql很类似 (1)sql和hql区别:sql操作表和表字段,hql操作实体和实体属性 (2)使用: 2.Criteria对象:不需要写语句 ...
- C# Log4Net 日志
C#使用Log4Net记录日志 第一步:下载Log4Net 下载地址:http://logging.apache.org/log4net/download_log4net.cgi ...
- guxh的python笔记七:抽象基类
1,鸭子类型和白鹅类型 1.1,白鹅类型 白鹅类型对接口有明确定义,比如不可变序列(Sequence),需要实现__contains__,__iter__,__len__,__getitem__,__ ...
- gulp下单页面应用打包
项目地址:https://pan.baidu.com/s/1cu4WW2 之前已经说过多入口打包,最近正好做一个单页面应用,之前多人口是用webpack打包的,但是感觉webpack比较重,单页面我又 ...
- leetcode-956. 最高的广告牌
https://leetcode-cn.com/contest/weekly-contest-114/problems/tallest-billboard/ 给出一个集合,询问能否挑出两个不重叠的子集 ...
- CopyOnWriteArrayList&Collections.synchronizedList()
1.ArrayList ArrayList是非线性安全,此类的 iterator() 和 listIterator() 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remov ...
- hashlib使用
提供摘要算法:主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法 import hashlib m = hashlib.md5("ddddd".e ...