装饰器语法糖运用

装饰器语法糖运用

  • 前言:函数名是一个特性的变量,可以作为容器的元素,也可以作为函数的参数,也可以当做返回值。

  • 闭包定义:

    • 内层函数对外层函数(非全局)变量的引用,这个内层函数就可以成为闭包

    • 在Python中我们用__closure__来检查函数是否是闭包

    • def func1():name = '张三'def func2():print(name)  # 能够访问到外层作用域的变量func2()print(func2.__closure__)  # (<cell at 0x1036c7438: str object at 0x10389d088>,)func1()
      print(func1.__closure__)  # None
  • 装饰器

    • 前言:软件设计原则:开闭原则,又称开放封闭原则

      • 指对扩展代码的功能是开放的,但对修改源代码是封闭的,
    • def create_people():print('女娲真厉害,捏个泥吹口气就成了人!')def a(func):def b():print('洒点水')func()return bret = a(create_people)
      ret()
    • 通过装饰器语法等同于

    • def a(func):def b():print('洒点水')func()return b@a  # 装饰器语法糖的作用就是上述函数ret()
      def create_people():print('女娲真厉害,捏个泥吹口气就成了人!')create_people()
  • 装饰带返回值的函数,即return出被装饰函数的执行结果

    • def foo(func):  # 接收的参数是一个函数名def bar():  # 定义一个内层函数print("这里是新功能...")  # 新功能r = func()  # 在内存函数中拿到被装饰函数的结果return r  # 返回被装饰函数的执行结果return bar# 定义一个有返回值的函数
      @foo
      def f1():return '嘿嘿嘿'# 调用被装饰函数
      ret = f1()  # 调用被装饰函数并拿到结果
      print(ret)
  • 装饰带参数的函数

    • def func1(func):              # 接收的参数为一个函数名def inner(*args, **kwargs):     # 这里需要定义和被装饰函数相同的参数print("新功能")                # 新功能ret = func(*args, **kwargs)     #被装饰的函数和参数print("新功能")         return retreturn inner# 定义一个需要俩个参数的函数
      @func1
      def func(a, b):return a + bret = func(3, 5)
      print(ret)
  • 带参数的装饰器 即在装饰器外在写一层函数,从而使其带参数

    • def d(a=None):        # 定义一个外层函数,给装饰器传参数def func1(func):  # 接收的是一个函数名def inner(*args, **kwargs): # 被装饰的函数,和参数if a:print(f"欢迎来到{a}")   #添加新功能else:print("欢迎来到王者荣耀")  func(*args, **kwargs)return innerreturn func1# @d("英雄联盟")
      # def func(st):
      #     print(st)
      # func("敌军还有三十秒到达战场")# 欢迎来到英雄联盟# 敌军还有三十秒到达战场@d()
      def func(st):print(st)
      func("敌军还有三十秒到达战场")
      # 欢迎来到王者荣耀
      # 敌军还有三十秒到达战场
  • 装饰器修复技术

    • 定义:被装饰的函数最终都会失去本来的__doc__等信息, Python给我们提供了一个修复被装饰函数的工具。

    • from functools import wraps    #导入
      print(f1.__doc__)
      print(f1.__name__)
  • 多个装饰器装饰同一函数

    • from functools import wrapsdef wrapper2(func):@wraps(func)def inner(*args, **kwargs):r = func(*args, **kwargs)return f"<2>{r}</2>"return innerdef wrapper1(func):@wraps(func)def inner(*args, **kwargs):r = func(*args, **kwargs)return f"<1>{r}</1>"return inner@wrapper2
      @wrapper1
      def func(a):return aprint(func("Hello World!!"))  #<2><1>Hello World!!</1></2>
    • def foo1(func):print("d1")def inner1():print("inner1")return "<i>{}</i>".format(func())return inner1def foo2(func):print("d2")def inner2():print("inner2")return "<b>{}</b>".format(func())return inner2@foo1
      @foo2
      def f1():return "Hello Andy"# f1 = foo2(f1)  ==> print("d2") ==> f1 = inner2
      # f1 = foo1(f1)  ==> print("d1") ==> f1 = foo1(inner2) ==> inner1ret = f1()  # 调用f1() ==> inner1()  ==> <i>inner2()</i>  ==> <i><b>inner1()</b></i> ==> <i><b>Hello Andy</b></i>
      print(ret)
  • 类装饰器

    • class D(object):def __init__(self, a=None):self.a = aself.mode = "装饰"def __call__(self, *args, **kwargs):if self.mode == "装饰":self.func = args[0]  # 默认第一个参数是被装饰的函数self.mode = "调用"return self# 当self.mode == "调用"时,执行下面的代码(也就是调用使用类装饰的函数时执行)if self.a:print("欢迎来到{}页面。".format(self.a))else:print("欢迎来到首页。")self.func(*args, **kwargs)@D()
      def index(name):print("Hello {}.".format(name))@D("电影")
      def movie(name):print("Hello {}.".format(name))if __name__ == '__main__':index('张三')movie('张三')
  • 装饰类

    • # 定义一个类装饰器
      class D(object):def __call__(self, cls):class Inner(cls):# 重写被装饰类的f方法def f(self):print('Hello 张三.')return Inner@D()
      class C(object):  # 被装饰的类# 有一个实例方法def f(self):print("Hello world.")if __name__ == '__main__':c = C()c.f()

转载于:https://www.cnblogs.com/yuncong/p/9886555.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450860.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

fb 4.7英文版 显示行数

窗口&#xff08;window&#xff09;首选项&#xff08;Preference&#xff09;—>常规&#xff08;General&#xff09;—>编辑器&#xff08;Editors&#xff09;—>文本编辑器&#xff08;Text Editors&#xff09;—>“显示行号”&#xff08;Show line number…

集市中迷失的一代:FreeBSD核心开发者反思开源软件质量

摘要&#xff1a;本文作者Poul-Henning Kamp (phkFreeBSD.org) &#xff0c;26年的计算机程序员&#xff0c;他编写的软件以底层构建块的形式广泛被开源和商业产品采用。讲述作者在看完《设计原本》这本书后所引发的共鸣&#xff01; 13年前&#xff0c;新兴的草根开源软件运动…

点击表格弹窗获取另外一套数据之后,原表格相关数据的调用

用H5新属性&#xff0c;data-*&#xff0c; $获取方式&#xff1a; 待续。。。。。。。 转载于:https://www.cnblogs.com/He-tao-yuan/p/9888316.html

谷歌浏览器如何如何禁用弹出窗口阻止程序

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 在工具栏上使用 Google Chrome 菜单。工具栏上的菜单位于浏览器右上角。 选择“设置”。 在页面底端找到并点击“显示高级设置”。 在“隐…

Python 3 入门,看这篇就够了

文章目录 简介基础语法运算符变量数据类型流程控制迭代器生成器函数 自定义函数参数传递 可更改与不可更改对象参数匿名函数变量作用域模块面向对象错误和异常文件操作序列化命名规范参考资料简介 Python 是一种高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。Pyt…

面试经历(二)

前面说到用数据库中的锁机制对并发事务进行控制&#xff0c;这节来说说事务方法和事务方法发生嵌套调用时事务如何进行传播。例如&#xff1a;方法可能继续在现有事务中运行&#xff0c;也可能开启一个新事务&#xff0c;并在自己的事务中运行。例如&#xff1a;方法可能继续在…

最有价值的编程忠告

摘要&#xff1a;本文是来自贝尔实验室Plan 9操作系统的创始人Rob Pike给大家分享的编程忠告&#xff01;Rob Pike&#xff0c;目前谷歌公司最著名的软件工程师之一&#xff0c;曾是贝尔实验室Unix开发团队成员&#xff0c;缔造Go语言和Limbo语言的核心人物。 Rob Pike&#xf…

Column count doesn't match value count at row 1 原因

mysql 提示 &#xff1a; Column count doesnt match value count at row 1错误&#xff0c;SQL语句中列的个数和值的个数不等&#xff0c; 如&#xff1a; insert into table1 (field1,field2) values(值1&#xff0c;值2&#xff0c;值3 ) 列只有2个&#xff0c;值 却有3个…

MarkDowm快捷键大全

文章目录一&#xff1a;菜单栏二&#xff1a;文件三&#xff1a;编辑四&#xff1a;段落五&#xff1a;格式六&#xff1a;视图一&#xff1a;菜单栏 文件&#xff1a;altF 编辑&#xff1a;altE 段落&#xff1a;altP 格式&#xff1a;altO 视图&#xff1a;altV 主题&#x…

Kinect2.0-空间长度测量

1. 鼠标左键按下选择起点&#xff0c;拖动鼠标&#xff0c;左键放开&#xff0c;确定终点。 实现效果1实现效果22. 在linux下使用libfreenect2开源多平台驱动来获取kinect2.0的传感器信息&#xff0c;得到深度信息&#xff0c;并通过libfreenect2提供的getPointXYZ函数&#xf…

带数据库的智能合约

编写使用数据库的智能合约 前面一直在捣鼓EOS网络搭建的相关东西。然而今天比较不走运的是&#xff0c;兴致勃勃的把源码版本升到4.0&#xff0c;在编译的时候如我所猜想的出现了一系列问题&#xff0c;正一筹莫展的时候&#xff0c;导师突然问了我一个关于合约如何操作数据库的…

没有完美的软件:编程永远不容易

摘要&#xff1a;很多人想用十全十美来修饰一样东西&#xff0c;比如软件&#xff0c;对于客户来说&#xff0c;当然希望他们的软件能做到完美。虽然很多专家说利用一些规范可以让软件达到更好&#xff01;但是在现实开发中&#xff0c;真的会有那么完美的软件吗&#xff1f; 最…

Eclipse断点调试出现Source not found

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 我的情况是和网上说的都不一样&#xff0c;我真的也没有想到这么坑&#xff0c; 我居然无意写了一个死循环&#xff0c;dao/mapper调sql…

Memory Compression这到底是个什么东西?

Memory Compression这到底是个什么东西&#xff1f; Memory Compression这个进程&#xff0c;经过我的查询说是内存压缩功能&#xff0c;作用是压缩内存让内存占用更低&#xff0c;但是为什么这个进程疯狂占用我的内存&#xff0c;我用的Win10 8G&#xff0c;通过资源监视器查看…

MySQL 5.6 for Windows 解压缩版配置安装

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 MySQL是一个小巧玲珑但功能强大的数据库&#xff0c;目前十分流行。但是官网给出的安装包有两种格式&#xff0c;一个是msi格式&#xf…

safari的一些问题

1、图片过大时&#xff0c;在webview中是不会加载显示的。2、如果是通过一个地址返回的base64数据给image&#xff0c;记住要在后台进行base64_decode解析数据&#xff0c;这样才是真实的图片数据&#xff0c;后台保存数据的时候不要保存"data:image/png;base64,"这一…

代码审查“思维导图”

摘要&#xff1a;随着人们对软件质量要求的不断提高&#xff0c;软件开发的每一个环节都应该得到十足的重视&#xff0c;俗话说&#xff1a;“细节决定成败”&#xff0c;就此&#xff0c;本文提供了一个代码审查“思维导图”&#xff0c;希望对所有码农们有所帮助。 代码审查&…

thinkCMF----导航高亮显示

导航高亮显示&#xff0c;有多种方法&#xff0c;这里给出一个简单的表示下&#xff1a; <a href"__ROOT__"><span class"text db">网站首页</span><span class"eng db">HOME</span> </a> …

The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 tomcat启动报务后访问页面报错&#xff1a; org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/co…

优秀程序员和一般程序员差别在哪?

摘要&#xff1a;在这个世界上有两种程序员&#xff1a;Day Programmers&#xff08;白班程序员&#xff09;和Night Programmers&#xff08;夜猫子程序员&#xff09;&#xff0c;你知道优秀程序员和一般程序员有哪些差别吗&#xff1f;你又是哪一类型的呢&#xff1f;俗话说…