一 闭包函数

内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,这个内函数叫做闭包函数

1.1 闭包函数语法

def outer():
a = 5
def inner():
print(a)
return inner

对比正常的局部变量

局部变量的生命周期最短,在调用结束之后,立即释放.

def func():
a = 5
print(a)
func()
print(a)

执行

1.2 闭包函数的定义

def bibao():
people = "孙仲谋"
def caocao_say():
print("生子当如%s" % (people))
return caocao_say func = bibao()
# func = caocao_say
func()

执行

[root@node10 python]# python3 test.py
生子当如孙仲谋

1.3 闭包函数的特点(升级)

  • 内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期(实际内存给它存储了这个值,暂时不释放)

示例

def grade(str1):
def func_in(str2):
print(str1+str2)
return func_in a=grade('小李:')
a('语文:118') b=grade('小红:')
b('语文:109')
b('数学:98')

执行

[root@node10 python]# python3 test.py
小李:语文:118
小红:语文:109
小红:数学:98

示例2

def family():
jiejie = "小红"
meimei = "小明"
money = 100 def jiejie_hobby():
nonlocal money
money -=40
print("姐姐%s喜欢买零食,买了辣条钱还剩下%s" % (jiejie,money))
return money def meimei_hobby():
nonlocal money
money -= 30
print("妹妹%s喜欢买衣服,还剩下%s" % (meimei,money))
return money def big_manager():
return (jiejie_hobby,meimei_hobby) return big_manager func = family()
# func = big_manager
print(func,type(func))
# func() = big_manager()
tup = func()
print(tup,type(tup)) # 调用姐姐
# jiejie = tup[0]
# jiejie() res1 = tup[0]()
print(res1)
# 调用妹妹
# meimei = tup[1]
# meimei() res2 = tup[1]()
print(res2)

执行

[root@node10 python]# python3 test.py
<function family.<locals>.big_manager at 0x7fee9c4f21e0> <class 'function'>
(<function family.<locals>.jiejie_hobby at 0x7fee9c4f20d0>, <function family.<locals>.meimei_hobby at 0x7fee9c4f2158>) <class 'tuple'>
姐姐小红喜欢买零食,买了辣条钱还剩下60
60
妹妹小明喜欢买衣服,还剩下30
30

示例3

def outer(val):
def inner(num):
return val + num
return inner func = outer(10)
# func = inner
res = func(5)
print(res)

执行

[root@node10 python]# python3 test.py
15

过程

    func = outer(10)
val 形参接收到实参值10
因为内函数使用了外函数的局部变量val,val与内函数发生绑定,延长val的生命周期
res = func(5)
num 形参接收到实参值5
return 10 + 5 => return 15 返回到函数的调用处
func(5) 是调用处 所以
res = 15

1.4 获取闭包函数使用的变量

闭包函数.__closure__  返回单元cell  , cell 里面存的是对应的绑定变量
res = func.__closure__ # 获取到一个元组
res = res[0].cell_contents # res[0] 获取元组当中的第一个值 是一个cell单元 通过单元.cell_contents来获取其中的值,就会知道绑定的变量是谁了. cell_contents是一个属性
print(res,type(res))
# print(res.cell_content)
# (<cell at 0x000001D6DAE17708: int object at 0x000000005EC26D30>,)

示例

def outer(val):
def inner(num):
return val + num
return inner func = outer(10)
# func = inner
res = func(5)
print(res)
print(func.__closure__)
print(func.__closure__,type(func.__closure__))
res = func.__closure__[0]
print(res,type(res)) res = func.__closure__[0].cell_contents
print(res,type(res))

执行

[root@node10 python]# python3 test.py
15
(<cell at 0x7fe07763b7f8: int object at 0x7fe07750c7e0>,)
(<cell at 0x7fe07763b7f8: int object at 0x7fe07750c7e0>,) <class 'tuple'>
<cell at 0x7fe07763b7f8: int object at 0x7fe07750c7e0> <class 'cell'>
10 <class 'int'>

1.5 闭包的意义

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

模拟鼠标点击次数

num = 0
def click():
global num
num += 1
return num
res = click()
res = click()
res = click()
# num = 100 恶意串改,我们获取的值就会出现错误
res = click()
res = click()
print(res)

使用闭包函数重写鼠标点击次数

def click():
x = 0
def func():
nonlocal x
x+=1
return x
return func click = click()
res = click()
res = click()
res = click()
x = 100 #恶意修改,但是不影响结果
res = click()
res = click()
print(res)

执行

[root@node10 python]# python3 test.py
5

二 locals 和 globals

2.1 locals()

返回字典,获取当前作用域的所有内容

  • 如果在函数里:获取locals()调用之前,该作用域出现的内容
  • 如果在函数外:获取locals()打印返回值之前,该作用域出现的内容
a = 1
b = 2
print(locals())

执行

[root@node10 python]# python3 test.py
{'__name__': '__main__',
'__doc__': None, 如果在函数里:获取locals()调用之前,该作用域出现的内容\n    如果在函数外:获取locals()打印返回值之前,该作用域出现的内容\n', 
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7ffa9ddb7208>,
'__spec__': None, '__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__file__': 'test.py',
'__cached__': None,
'a': 1,
'b': 2,
'func': <function func at 0x7ffa9de8ae18>, #全局中又这个函数,但是函数内部的局部变量不能获取
'res': {...},
'c': 3}

所在作用域是局部命名空间,获取locals() 调用之前所出现的所有局部命名空间内容

c=3
d = 4
def func():
a = 1
b = 2 res = locals()
c = 3
print(res) f = 5
func()

执行

[root@node10 python]# python3 test.py
{'b': 2, 'a': 1}

2.2 globals()

返回字典,获取全局作用域的所有内容

  • 如果在函数里: 获取globals()调用之前,全局作用域出现的内容
  • 如果在函数外: 获取globals()打印返回值之前,全局作用域出现的内容

globals在全局作用域中,只获取globals 打印返回值之前的所有全局空间的内容

a = 1
b = 2
res = globals()
print(res)
c = 3

执行

[root@node10 python]# python3 test.py
{'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fcd746f5208>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__file__': 'test.py',
'__cached__': None,
'a': 1,
'b': 2,
'res': {...}}

globals在局部作用域中,也仍然获取全局空间的所有内容,但是是在globals,打印返回值之前的所有.

c = 13
d = 14
def func():
a = 11
b = 12
res = globals()
print(res)
f = 19
func()

执行

[root@node10 python]# python3 test.py
{'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f16a5144208>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module
'builtins' (built-in)>,
'__file__': 'test.py',
'__cached__': None,
'c': 13,
'd': 14,
'func': <function func at 0x7f16a5217e18>,
'f': 19}

只获取全局,没有ab的值

动态创建全局变量 利用globals

  • globals 返回的是一个系统的全局字典,键是变量名,值是该标量所指向的值
dic = globals()
dic['hero'] = "风流倜傥,高大威猛,威武帅气,万人迷"
print(hero) # 动态创建5个全局变量p1~p5
def func():
for i in range(1,6):
dic["p%d" % (i)] = i func()
print(p1)
print(p2)
print(p3)
print(p4)
print(p5)

执行

[root@node10 python]# python3 test.py
风流倜傥,高大威猛,威武帅气,万人迷
1
2
3
4
5

016.Python闭包函数以及locals和globals的更多相关文章

  1. python学习笔记012——locals与globals

    1 定义 globals() 功能:收集全局变量参数:无返回值:得到一个收集全局变量的字典(会包含系统的内置变量) locals() 功能:收集局部变量参数:无返回值:得到一个收集局部变量的字典 a ...

  2. python之函数用法locals()

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法locals() #locals() #说明:查找局部变量,返回一个名字/值对的字典对 ...

  3. python闭包函数与装饰器

    目录 闭包函数 闭包概念 实际应用 装饰器 简介 简单版本装饰器 进阶版本装饰器 完整版本装饰器 装饰器模板 装饰器语法糖 装饰器修复技术 问题 答案 闭包函数 闭包概念 闭:定义在函数内部的函数 包 ...

  4. python闭包函数、装饰器

    闭包函数的传值方式: 方式1:通过参数传值 def func(x): print(x)func(1) 方式2:闭包函数传值 def outter(x): def inner(): print(x) r ...

  5. Python闭包函数

    闭包 闭包:python中的闭包从表现形式上定义(解释)为: 如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 先看一个函数: ...

  6. python 闭包函数与装饰器

    1.什么是闭包函数 (1):什么是闭包函数: #内部函数包含对外部作用域而非全局作用域的引用, 简而言之, 闭包的特点就是内部函数引用了外部函数中的变量. 在Python中,支持将函数当做对象使用,也 ...

  7. python闭包函数&装饰器

    一.函数引用 函数可以被引用 函数可以被赋值给一个变量 def hogwarts(): print("hogwarts") # hogwarts() # 函数调用 print(ho ...

  8. python闭包函数及装饰器简介

    目录: 闭包函数简介 闭包函数的实际应用 装饰器简介 装饰器初期-完整版 装饰器语法糖 闭包函数简介 1.定义在函数内部的函数(函数的嵌套) 2.内部函数运用外部函数局部名称空间中的变量名 注:函数名 ...

  9. 跟着太白老师学python day11 函数名的应用 globals(), locals()

    1.  函数名就是内存地址 def func(): ') print(func) >>>> <function func at 0x00000000003DC1E0> ...

随机推荐

  1. HTML(〇):简介导读

    网页 什么是网页 网站(Website):是指在因特网上根据一定的规则,使用HTML(标准通用标记语言)等工具制作的用于展示特定内容相关网页的集合. 网页(webpage):是网站中的一页,通常是HT ...

  2. 黑马架构师v2.5.1 (codeUtil)使用注意事项

    资源 1.资料里的codeutil软件有问题,使用时部分类和接口文件名后有一串日期数字等.码云的没问题 2.生成代码后zookeeper的IP改为本机的

  3. C语言-字符串函数的实现(五)之strstr

    C语言中的字符串函数有如下这些 获取字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strncat strncmp ...

  4. 12.Quick QML-QML 布局(Row、Column、Grid、Flow和嵌套布局) 、Repeater对象

    1.Row布局 Row中的item可以不需要使用anchors布局,就能通过行的形式进行布局. 并且item可以使用Positioner附加属性来访问有关其在Row中的位置及其他信息. 示例如下所示, ...

  5. 手写Spring DI依赖注入,嘿,你的益达!

    目录 提前实例化单例Bean DI分析 DI的实现 构造参数依赖 一:定义分析 二:定义一个类BeanReference 三:BeanDefinition接口及其实现类 四:DefaultBeanFa ...

  6. 生成https证书脚本

    [root@yc1 ~]# cat yc_https.sh #!/bin/bash hostname=192.168.23.140 rm -rf /etc/pki/CA &>/dev/n ...

  7. SLAM导航及控制部分,源码公布

    欢迎Fork,觉得不错就点个小星星吧 ROS源码 https://github.com/ShieldQiQi/TX2_StereoSLAM STM32驱动板源码 https://github.com/ ...

  8. Android Hook框架adbi的分析(3)---编译和inline Hook实践

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/75200800 一.序言 在前面的博客中,已经分析过了Android Hook框架a ...

  9. WPScan工具的使用(WordPress扫描工具)

    WPScan是Kali Linux默认自带的一款漏洞扫描工具,它采用Ruby编写,能够扫描WordPress网站中的多种安全漏洞,其中包括WordPress本身的漏洞.插件漏洞和主题漏洞.最新版本WP ...

  10. UVA11427玩纸牌(全概率+递推)

    题意:       一个人玩纸牌游戏,他每天最多玩n局,枚举获胜的概率是a/b,每天玩牌只要获胜概率达到p,那么他今天就不玩了,明天接着玩,如果有一天他的概率没有达到p,(没有达到p的话他今天一定是玩 ...