python闭包和装饰器如何理解,怎样使用?
Admin 2021-05-31 群英技术资讯 1426 次浏览
对一些新手来说python闭包和装饰器是比较难理解的内容,为帮助大家更好的理解和学习python闭包和装饰器,下面给大家介绍一些关于python闭包和装饰器的实例,需要的朋友可以参考学习。
闭包的形成条件:
1.函数嵌套。
2.内部函数使用了外部函数的变量或者参数。
3.外部函数返回了使用外 部变量的内部函数。
def func_out(num1): def inner(num2): res = num1 + num2 print(res) return inner # a = func_out(10)(10) a = func_out(10) a(10)
闭包修改外部函数的变量:
在闭包内修改外部函数的变量需要使用nonlocal关键字
def func_out(): # 外部函数的变量 num1 = 10 def func_inner(): # 在闭包内修改外部函数的变量 nonlocal num1 num1 = 20 res = num1 +20 print(res) print("修改前的变量", num1) func_inner() print("修改后的变量", num1) return func_inner new_func = func_out() new_func()
装饰器就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数,也就是说也是一个函数嵌套。装饰器的功能特点:
1.不修改已有函数的源代码
2.不修改已有函数的调用方式
3.给已有函数增加额外的功能
用户在发表评论的时候需要验证用户是否登录,我们首先会想到去修改原来的函数,在函数里面添加一些功能,但是在现在这分工合作的时代,这样的修改很容易出现修改了祖传的代码后,函数出现问题,也影响代码的高效复用。为了能够不重新修改原来的评论的代码,实现高水平的代码复用。
原本的函数及其调用:
def comment(): print("执行祖传代码.....") print("发表评论") # 调用评论功能 comment()
自己手写一个实现装饰器功能的函数实现登录验证:
def decorator(func): def inner(): print('正在验证登录者身份...\n验证成功') func() return inner def comment(): print("执行祖传代码.....") print("发表评论") # 调用评论功能 comment = decorator(comment) comment()
输入结果:
正在验证登录者身份…
验证成功
执行祖传代码…
发表评论
装饰器的语法糖写法:@装饰器名称
如例子可以改写为:
def decorator(func): def inner(): print('正在验证登录者身份...\n验证成功') func() return inner @decorator def comment(): print("执行祖传代码.....") print("发表评论") # 调用函数 comment()
运行结果:
正在验证登录者身份…
验证成功
执行祖传代码…
发表评论
先说结论:在使用装饰器语法糖时,会先将该装饰器函数执行一遍。
def decorator(func): # 测试装饰器的执行时机 print('--remark1----') def inner(): print('正在验证登录者身份...\n验证成功') func() print('----remark2---') return inner @decorator def comment(): print("执行祖传代码.....") print("发表评论")
输出结果:
--Cremark1----
----remark2―
装饰的函数可能有参数传递,或者有返回值,上面写的例子中,如果依然用上面的方法及逆行装饰器的装饰将会出现问题,那是否有一个通用的装饰器能够装饰任意函数呢?
def logging(fn): def inner(num1,num2): print('执行了一次计算') fn(num1,num2) return inner # 使用装饰器装饰函数 @logging def sum_num(a,b): result = a + b print(result) sum_num(1,2)
def logging(fn): def inner(num1,num2): print('执行了一次计算') result = fn(num1,num2) return result return inner # 使用装饰器装饰函数 @logging def sum_num(a,b): result = a + b return result print(sum_num(1,2))
*args
: 用于接收元组参数,可传可不传
**kwargs
: 用于接收字典类型参数,可传可不传
def logging(fn): def inner(*args, **kwargs): result = fn(*args, **kwargs) return result return inner @logging def sum_num(a,b): result = a + b return result
多个装饰器的过程:由内到外的装饰过程,先执行内部装饰器,再执行外部装饰器。
原理剖析:content = make_div(make_p(content))
分步拆解:content = make_p(content), 内部装饰器完成content=make_p.inner, content = make_div(make_p.inner)
def make_div(func): print("make_div装饰器执行了") def inner(): # 在内部函数对已有函数进行装饰 result = "<div>" + func() +"</div>" return result return inner def make_p(func): print("make_p装饰器执行了") def inner(): # 在内部函数对已有函数进行装饰 result = "<p>" + func() +"</p>" return result return inner @make_div @make_p def content(): return "人生苦短,我用Python"
输出:
make_p装饰器执行了
make_div装饰器执行了
<div><p>人生苦短,我用Python</p></div>
带有参数的装饰器时机上就是定义了一个函数,让函数接收参数,再函数内部返回该装饰器。
如定义一个能够判断加减的装饰器:
def return_decorator(flag): def decorator(func): def inner(a,b): if flag == '+': print("正在进行加法运算") elif flag == '-': print("正在进行减法运算") func(a,b) return inner return decorator @return_decorator('+') def add_num(a,b): print(a+b) add_num(1,5)
使用类装饰已有函数。
class MyDecorator(object): def __init__(self,func): self.__func = func # 实现__call__方法,让对象变成可调用的对象, # 可调用的对象能够像函数一样被使用。 def __call__(self,*args,**kwargs): # 对已有参数进行封装 print('--正在进行装饰-----') self.__func() @MyDecorator def show(): print("hello") # 指向MyDecorator类创建实例对象--> show()==> 对象() show()
输出:
--C正在进行装饰-----
hello
关于python闭包和装饰器的相关内容就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果想要了解更多python闭包和装饰器,大家可以关注其他相关文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要为大家介绍了python神经网络Pytorch中Tensorboard常用函数的使用示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,pyecharts 诞生了。
如果要考察某公司的牛奶产品质量,可以从100袋牛奶中抽取30袋,在随机数表中选中一数,并用向上、下、左、右不同的读法组成30个数,并按牛奶的标号进行检测,虽然麻烦,但很常用。在日常生活中,随机数起着很大的作用,所以很多人会专门去寻找随机数生成器。
python中,while循环与for循环是经常使用的循环语句,一直到的到结果才会循环结束。但是,也会有一直循环,无法计算出结果的情况出现,这时我们就要跳出循环。本文介绍使用break跳出for循环的两种方法:1、提前定义一个变量,让其为空字符串;2、使用for…else…实现break跳出嵌套的for循环。
今天小编给大家分享10个Python高级脚本,帮助我们减少无谓的时间浪费,提高工作学习中的效率。文中示例代码讲解详细,需要的可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008