一、概念

"""
如果内函数使用了外函数的局部变量,
并且外函数把内函数返回出来的过程,叫做闭包
里面的内函数是闭包函数
"""

二、基本语法

def songyunjie_family():
father = "王健林"
def f_hobby():
print("我们先顶一个小目标,比如赚它一个亿,这是我爸爸{}".format(father))
return f_hobby func = songyunjie_family()
func() obj = func.__closure__[0]
print(obj.cell_contents,"<111>")

三、复杂版本

def mashengping_family():
father = "马云"
jiejie_name = "马蓉"
meimei_name = "马诺"
money = 1000 def jiejie():
nonlocal money
money -= 700
print("买包包,买名表,买首饰,把钱都败光了,家里的钱还剩下{}元".format(money)) def meimei():
nonlocal money
money -= 200
print("要找只找有钱人,宁愿在宝马里面哭,也不愿意在自行车上撒欢,家里的败光了还剩下{}元".format(money)) def big_master():
return (jiejie,meimei) return big_master func = mashengping_family()
print(func)
# 返回的是元组
tup = func() # big_master()
print(tup) # tup = (jiejie,meimei)
# 获取姐姐
jiejie = tup[0] # jiejie 函数
# 获取妹妹
meimei = tup[1] # meimei 函数 # big_master 是闭包函数,是直接被mashengping_family返回出来的
# jiejie,meimei 是通过big_master间接被返回到函数外面的
# 调用妹妹
meimei() # 调用妹妹函数
# 调用姐姐
jiejie() # 调用姐姐函数 #看它是不是闭包函数,是就可以用
# cell获取单元格对象结果是一个函数名
# 加() 运行
# ### 获取闭包函数使用的变量 __closure__
res = func.__closure__
print(res,"<222>")
# cell_contents 用来获取单元格对象当中的闭包函数
jiejie = res[0].cell_contents
meimei = res[1].cell_contents # 通过获取单元格对象 -> 获取单元格对象中的内容 -> 实际的调用
jiejie()
meimei() print(jiejie.__closure__[0].cell_contents)
print(meimei.__closure__[0].cell_contents)

四、闭包的特征和意义

1、特征

"""
内函数使用了外函数的局部变量
那么该变量与闭包函数发生绑定,
延长该变量的生命周期
"""
def outer(val):
def inner(num):
return val + num
return inner func = outer(10) # func = inner
res = func(15) # res = func(15) = inner(15)
print(res)
"""
10实参 -> val 形参
因为内函数inner是闭包函数,使用了外函数val
那么该变量val生命周期被延长,没有随着函数调用的结束而释放.
func(15) 把15这个参数赋值给num这个形参
res = inner(15) => return val + num =>10 + 15 => 25
"""

2、意义

引入:

# 模拟鼠标点击次数
num = 0
def click_num():
global num
num += 1
print(num) click_num()
click_num()
click_num()
num = 100
click_num()
click_num()

2.1 使用闭包函数改写点击次数

闭包的意义:闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.

def click_num():
num = 0
def func():
nonlocal num
num += 1
print(num)
return func
func = click_num()
func()
func()
num = 1000
func()
func()
func()
func()
func()

五、匿名函数

 用一句话来表达只有返回值的函数
"""语法:lambda 参数 : 返回值 """
"""追求代码:简洁,高效"""

1、无参的lambda表达式

def func():
return "" # 改写
func = lambda : ""
res = func()
print(res)

2、有参的lambda 表达式

def func(n):
return type(n) # 改写
func = lambda n : type(n)
print( func([1,2,3]) )

3、带有判断条件的lambda 表达式

def func(n):
if n % 2 == 0:
return "偶数"
else:
return "奇数" func = lambda n : "偶数" if n % 2 == 0 else "奇数"
res = func(17)
print(res) # ### 三元(目)运算符
"""
语法:
真值 if 条件表达式 else 假值 如果条件表达式为真,返回真值,否则返回假值
"""
n = 16
res = "偶数" if n % 2 == 0 else "奇数"
print(res)

4、小练习:传递两个数, 返回较大的那一个

def func(x,y):
if x>y:
return x
else:
return y func = lambda x,y : x if x>y else y
res = func(200,100)
print(res)

六、练习

#下面代码成立么?如果不成立为什么报错?怎么解决?
#
# a = 2
# def wrapper():
# print(a)
# wrapper() #
# a = 2
# def wrapper():
# a += 1
# print(a)
# wrapper() #
# a = 2
# def wrapper():
# global a
# a += 1
# print(a)
# wrapper() #
# def wrapper():
# a = 1
# def inner():
# print(a)
# inner()
# wrapper() #
# def wrapper():
# a = 1
# def inner():
# a += 1
# print(a)
# inner()
# wrapper() #
# def wrapper():
# a = 1
# def inner():
# nonlocal a
# a += 1
# print(a)
# inner()
# wrapper()

# a = 2
# def wrapper():
# print(a)
# wrapper() # 成立

1

# a = 2
# def wrapper():
# a += 1
# print(a)
# wrapper()
# 不成立 局部变量不能修改全局变量
# 解决:
# a = 2
# def wrapper():
# global a
# a += 1
# print(a)
# wrapper()

2

# a = 2
# def wrapper():
# global a
# a += 1
# print(a)
# wrapper()
# 成立

3

# def wrapper():
# a = 1
# def inner():
# print(a)
# inner()
# wrapper()
# 成立

4

# def wrapper():
# a = 1
# def inner():
# a += 1
# print(a)
# inner()
# wrapper()
# 不成立
# 要通过 nonlocal引入 a
# def wrapper():
# a = 1
# def inner():
# nonlocal a
# a += 1
# print(a)
# inner()
# wrapper()

5

def wrapper():
a = 1
def inner():
nonlocal a
a += 1
print(a)
inner()
wrapper()
# 成立

6

day12. 闭包的更多相关文章

  1. day12闭包,装饰器

    一.闭包:内部函数引用了外部函数的变量. # f1() #闭包的定义 #内部的函数引用了外部函数的变量 # def f1(b): #闭包的常用状态 # def f2(): # print(b) # r ...

  2. day12 python函数名的应用 闭包 迭代器

    day12 python   一.函数名的应用(是第一类对象)     函数名的命名规范和变量是一样的     函数名其实就是变量名 def func():     print('i am funct ...

  3. python学习day12 函数Ⅳ (闭包&内置模块)

    函数Ⅳ (闭包&内置模块) 1.内置函数(补充) lambda表达式也叫匿名函数. 函数与函数之间的数据互不影响,每次运行函数都会开一个辟新的内存. item = 10 def func(): ...

  4. day12 函数的嵌套调用 闭包函数,函数对象

    函数嵌套: 函数嵌套: 嵌套指的是,一个物体包含另一个物体,函数嵌套就是一个函数包含另一个函数 按照函数的两个阶段 嵌套调用 指的是在函数的执行过程中调用了另一个函数,其好处可以简化外层大函数的代码, ...

  5. 【学习笔记】--- 老男孩学Python,day12 函数名的应用,闭包,迭代器

    1, 函数名的应用,第一类对象 函数名可以像变量一样进行使用 1.赋值 def func(): print("你吃了么?") # print(func) # a = func # ...

  6. Python之函数2 嵌套,作用域和闭包(Day12)

    一.函数对象 1.函数是第一类对象,即函数可以当做数据传递 1.1 可以被引用 1.2 可以当做参数传递 1.3 返回值可以是函数 1.4 可以当做容器类型的元素 二.函数的嵌套 1.函数嵌套的调用: ...

  7. day12:闭包函数&匿名函数

    闭包函数 闭包函数的定义: 如果内函数使用了外函数的局部变量并且外函数把内函数返回出来的过程 叫做闭包里面的内函数是闭包函数 一个简单的闭包函数示例: def songyunjie_family(): ...

  8. day12 函数嵌套

    day12 函数嵌套 一. args与kwargs def index(a,b,c): print(a,b,c) def wrapper(*args,**kwargs): # args=(1,2,3) ...

  9. 《Web 前端面试指南》1、JavaScript 闭包深入浅出

    闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...

随机推荐

  1. MRCTF 2020-“TiKi小组”

    题目状态: OPEN - 正在试图解这道题CLOSED - 这道题还没有打开SOLVED - 解决了!鼓掌撒花! 赛事信息 Flag格式:MRCTF{}起止时间:2020-03-27 18:00:00 ...

  2. 线下---复习day02

    目录 1 后续课程安排 2 作业讲解 3 python中的魔法方法 setattr,getattr,setitem,getitem演示 with 上下文管理器 eq 4 cookie,session, ...

  3. asp.net mvc企业实战技能汇总

  4. adb devices 不能连接设备 could not install *smartsocket* listener

    cmd以管理员身份运行命令adb devices  或adb reverse tcp:8081 tcp:8081,无法连接设备,出现上图信息. 输入命令:adb kill-server 再输入:adb ...

  5. 三种存储方式DAS、NAS、SAN

    ------------恢复内容开始------------ 一.DAS.NAS.SAN在存储领域的位置 随着主机.磁盘.网络等技术的发展,数据存储的方式和架构也在一直不停改变,本文主要介绍目前主流的 ...

  6. 简单讲解一下http2的多路复用

    在 HTTP/1 中,每次请求都会建立一次HTTP连接,也就是我们常说的3次握手4次挥手,这个过程在一次请求过程中占用了相当长的时间,即使开启了 Keep-Alive ,解决了多次连接的问题,但是依然 ...

  7. java 面向对象(五):类结构 方法(二) 关键字:return;方法的重载;可变个数形参的方法

    return关键字:1.使用范围:使用在方法体中2.作用:① 结束方法 * ② 针对于返回值类型的方法,使用"return 数据"方法返回所要的数据.3.注意点:return关键字 ...

  8. 在spyder中无法import module

    如果在anaconda中下载安装了模块,但是在spyder中无法import,可能是因为两个python环境并不一致,在promote重新conda install spyder即可

  9. XML解析---利用XStream解析xml数据及反构造Java对象

    XStream 是一个轻量级的.简单易用的开放源代码 Java库,用于将 Java 对象序列化为 XML 或者再转换回来.而且XStream还能将java对象转成其它格式,比如JSon. 需要用到的包 ...

  10. SpringBoot2 整合FreeMarker模板,完成页面静态化处理

    本文源码:GitHub·点这里 || GitEE·点这里 一.页面静态化 1.动静态页面 静态页面 即静态网页,指已经装载好内容HTML页面,无需经过请求服务器数据和编译过程,直接加载到客户浏览器上显 ...