一、概念

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

二、基本语法

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. TLS回调函数以及反调试简单使用

    TLS回调函数以及反调试简单使用 0x00  TLS介绍 TLS(Thread Local Storage,线程局部储存),主要用于给线程独立的传值,由于线程不拥有进程的资源,所以几个同一进程的几个线 ...

  2. 实战SpringCloud通用请求字段拦截处理

    背景 以SpringCloud构建的微服务系统为例,使用前后端分离的架构,每个系统都会提供一些通用的请求参数,例如移动端的系统版本信息.IMEI信息,Web端的IP信息,浏览器版本信息等,这些参数可能 ...

  3. requests接口自动化1-json序列化与反序列化

    json序列化与反序列化: 序列化:将对象转换为json字符串 反序列化:将json字符串转换为对象,比如转换为python里的字典 import json #定义字典 dict1={'usernam ...

  4. less基础

    less less的含义: less是一种动态样式语言,属于css预处理器的范畴,它扩展了css语言,增加了变量.Mixin.函数等特性,使css更易维护和扩展. 此外,less既可以在客户端上运行, ...

  5. JavaScript动画实例:曲线的绘制

    在“JavaScript图形实例:曲线方程”一文中,我们给出了15个曲线方程绘制图形的实例.这些曲线都是根据其曲线方程,在[0,2π]区间取一系列角度值,根据给定角度值计算对应的各点坐标,然后在计算出 ...

  6. redis未授权访问简单总结

    redis环境搭建 下载有漏洞的redis版本 wget http://download.redis.io/releases/redis-3.2.11.tar.gz 编译文件 make 进入src目录 ...

  7. Html笔试复习

    掌握学习技巧,提高学习质量 学习目标:熟练掌握Html笔试复习题 已掌握目标:Html笔试复习题掌握95% 未完成目标:个别题因粗心造成错误,因选项意思不懂出错 解决方案:了解原因,因错出方案,充分利 ...

  8. xilinx fpga中块ram的使用——简单双端口ram的使用

    在简单双端口ram中最简单有9个端口:分别是 clka  为输入端口的时钟 wea  读写控制端,高为写,低为读 addra 写地址 dina  待写入的数据 clkb 为输出端口的时钟的 addrb ...

  9. .Net Core 常见错误解决记录

    Error: String or binary data would be truncated. The statement has been terminated 数据库出错原因: 表字段创建的太短 ...

  10. 一文了解JDK12 13 14 GC调优秘籍-附PDF下载

    目录 简介 那些好用的VM参数 G1的变化 配置FlightRecorder RAM参数 JDK13中的ZGC RTM支持 总结 简介 想了解JDK12,13,14中的GC调优秘籍吗?想知道这三个版本 ...