闭包、装饰器

注意:使用装饰器,最终都会改变装饰函数的函数名称及所属属性,所以在实际的装饰器中如果后续会涉及用到装饰函数函数名或所属属性的,需要加入python自带的模块@wraps确保函数装饰后,不会产生函数名及所属属性的改变。示例如下:

# 1 未加入@wraps装饰器
# coding=utf-8
from functools import wraps
def my_decorator(func):    def wrapper(*args, **kwargs):        '''decorator'''        print('Decorated function...')        return func(*args, **kwargs)    return wrapper
@my_decorator
def test():    """Testword"""     print('Test function')
print(test.__name__, test.__doc__)# 打印结果:
"""
wrapper decorator
[Finished in 0.1s]
"""# 2 加入@wraps装饰器
from functools import wraps
def my_decorator(func):    @wraps(func)    def wrapper(*args, **kwargs):        '''decorator'''        print('Decorated function...')        return func(*args, **kwargs)    return wrapper@my_decorator
def test():    """Testword"""     print('Test function')
print(test.__name__, test.__doc__)# 打印结果:
"""
test Testword
[Finished in 0.1s]
"""
  • 闭包

        # 定义:在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包def line_6(k, b):def create_y(x):print(k*x+b)return create_yline_6_1 = line_6(1, 2)line_6_1(0)line_6_1(1)line_6_1(2)line_6_2 = line_6(11, 22)line_6_2(0)line_6_2(1)line_6_2(2)# 思考:函数、匿名函数、闭包、对象 当做实参时 有什么区别?# 1. 匿名函数能够完成基本的简单功能,,,传递是这个函数的引用 只有功能# 2. 普通函数能够完成较为复杂的功能,,,传递是这个函数的引用 只有功能# 3. 闭包能够将较为复杂的功能,,,传递是这个闭包中的函数以及数据,因此传递是功能+数据# 4. 对象能够完成最为复杂的功能,,,传递是很多数据+很多功能,因此传递是功能+数据
    
  • 装饰器
    • 不带参数的装饰器
      ```python
      def set_func(func):
      def call_func():
      print("---这是权限验证1----")
      print("---这是权限验证2----")
      func()
      return call_func

        @set_func  # 等价于test1 = set_func(test1) def test1():print("-----test1----")test1()# 打印结果:"""---这是权限验证1-------这是权限验证2---------test1----[Finished in 0.1s]"""

      ```

    • 带参数的装饰器
      • 带一个参数
        ```python
        def set_func(func):
        def call_func(a):
        print("---这是权限验证1----")
        print("---这是权限验证2----")
        func(a)
        return call_func

          @set_func  # 相当于 test1 = set_func(test1)def test1(num):print("-----test1----%d" % num)test1(100)# 打印结果:"""---这是权限验证1-------这是权限验证2---------test1----100[Finished in 1.3s]"""```
        • 带多个参数
          ```python
          def set_func(func):
          print("---开始进行装饰")
          def call_func(*args, **kwargs):
          print("---这是权限验证1----")
          print("---这是权限验证2----")
          # func(args, kwargs) # 不行,相当于传递了2个参数 :1个元组,1个字典
          func(*args, **kwargs) # 拆包
          return call_func

          @set_func # 相当于 test1 = set_func(test1)
          def test1(num, *args, **kwargs):
          print("-----test1----%d" % num)
          print("-----test1----" , args)
          print("-----test1----" , kwargs)

          test1(100)
          test1(100, 200)
          test1(100, 200, 300, mm=100)

          # 打印结果:
          """
          ---开始进行装饰
          ---这是权限验证1----
          ---这是权限验证2----
          -----test1----100
          -----test1---- ()
          -----test1---- {}
          ---这是权限验证1----
          ---这是权限验证2----
          -----test1----100
          -----test1---- (200,)
          -----test1---- {}
          ---这是权限验证1----
          ---这是权限验证2----
          -----test1----100
          -----test1---- (200, 300)
          -----test1---- {'mm': 100}
          [Finished in 0.2s]
          ```

    • 通用类的装饰器
      ```python
      # 通用类装饰器
      def set_func(func):
      print("---开始进行装饰")
      def call_func(*args, **kwargs):
      print("---这是权限验证1----")
      print("---这是权限验证2----")
      # func(args, kwargs) # 不行,相当于传递了2个参数 :1个元组,1个字典
      return func(*args, **kwargs) # 拆包
      return call_func

        @set_func  # 相当于 test1 = set_func(test1)def test1(num, *args, **kwargs):print("-----test1----%d" % num)print("-----test1----" , args)print("-----test1----" , kwargs)return "ok"@set_funcdef test2():passret = test1(100)print(ret)ret = test2()print(ret)# 打印结果:""""""```
      • 对带有返回值的函数进行装饰
      def set_func(func):print("---开始进行装饰")def call_func(*args, **kwargs):print("---这是权限验证1----")print("---这是权限验证2----")# func(args, kwargs)  # 不行,相当于传递了2个参数 :1个元组,1个字典return func(*args, **kwargs)  # 拆包return call_func@set_func  # 相当于 test1 = set_func(test1)
      def test1(num, *args, **kwargs):print("-----test1----%d" % num)print("-----test1----" , args)print("-----test1----" , kwargs)return "ok"@set_func
      def test2():passret = test1(100)
      print(ret)ret = test2()
      print(ret)# 打印结果:
      # 装饰器使用return返回func,被装饰函数有return的返回return结果,没有发返回
      # 没有return的返回None,不影响实际的使用
      """
      ---开始进行装饰
      ---开始进行装饰
      ---这是权限验证1----
      ---这是权限验证2----
      -----test1----100
      -----test1---- ()
      -----test1---- {}
      ok
      ---这是权限验证1----
      ---这是权限验证2----
      None
      [Finished in 0.1s]
      """
    • 一个装饰器装饰多个函数
      ```python
      def set_func(func):
      def call_func(a):
      print("---这是权限验证1----")
      print("---这是权限验证2----")
      func(a)
      return call_func

        @set_func  # 相当于 test1 = set_func(test1)def test1(num):print("-----test1----%d" % num)@set_func  # 相当于 test2 = set_func(test2)def test2(num):print("-----test2----%d" % num)test1(100)test2(200)# 打印结果:"""---这是权限验证1-------这是权限验证2---------test1----100---这是权限验证1-------这是权限验证2---------test2----200[Finished in 0.2s]    """

      ```

    • 多个装饰器装饰一个函数
      ```python
      # 多个装饰器对一个函数进行装饰:
      def add_qx(func):
      print("---开始进行装饰权限1的功能---")
      def call_func(*args, **kwargs):
      print("---这是权限验证1----")
      return func(*args, **kwargs)
      return call_func

        def add_xx(func):print("---开始进行装饰xxx的功能---")def call_func(*args, **kwargs):print("---这是xxx的功能----")return func(*args, **kwargs)return call_func@add_qx@add_xxdef test1():print("------test1------")test1()# 打印结果:"""---开始进行装饰xxx的功能------开始进行装饰权限1的功能------这是权限验证1-------这是xxx的功能----------test1------[Finished in 0.1s] """# 实例:def set_func_1(func):def call_func():# "<h1>haha</h1>"return "<h1>" + func() + "</h1>"return call_funcdef set_func_2(func):def call_func():return "<td>" + func() + "</td>"return call_func@set_func_1@set_func_2def get_str():return "haha"print(get_str())# 打印结果:"""<h1><td>haha</td></h1>[Finished in 0.1s]"""

      ```

    • 类装饰器
      ```python
      class Test(object):
      def init(self, func):
      self.func = func

            def __call__(self):print("这里是装饰器添加的功能.....")return self.func()@Test  # 相当于get_str = Test(get_str)def get_str():return "haha"print(get_str())  # 实际会调用__call__方法# 打印结果:"""这里是装饰器添加的功能.....haha[Finished in 0.2s]"""

      ```

转载于:https://www.cnblogs.com/achjiang/p/9908010.html

python基础---闭包、装饰器相关推荐

  1. python装饰器-Python基础-20装饰器

    20.装饰器 20.1 函数基础知识 在Python中函数为一等公民,我们可以: 把函数赋值给变量 在函数中定义函数 在函数中返回函数 把函数传递给函数 20.1.1 把函数赋值给变量 在Python ...

  2. Python成长之路【第七篇】:Python基础之装饰器

    一.什么是装饰器 装饰:装饰既修饰,意指为其他函数添加新功能 器:器既函数 装饰器定义:本质就是函数,功能是为其他函数添加新功能 二.装饰器需要遵循的原则 1.不能修改装饰器的源代码(开放封闭原则) ...

  3. python高级-闭包-装饰器

    闭包内容: 匿名函数:能够完成简单的功能,传递这个函数的引用,只有功能 普通函数:能够完成复杂的功能,传递这个函数的引用,只有功能 闭包:能够完成较为复杂的功能,传递这个闭包中的函数以及数据,因此传递 ...

  4. python基础学习-装饰器进阶

    #__author:"Feng Lin" #date: 2018/8/30 #装饰器进阶 # functool.wraps # 带参数的装饰器 # 多个装饰器装饰同一个函数from ...

  5. python基础-装饰器

    什么是装饰器 # 概念:就是接受一个函数不改变里面的代码,进行包裹,然后返回函数的一个工具:不改变原函数调用方法的,对原函数进行包裹附加功能的工具 # 原理:利用高阶函数可以接受函数作为参数,返回函数 ...

  6. 【Python成长之路】python 基础篇 -- 装饰器【华为云分享】

    [写在前面] 有时候看到大神们的代码,偶尔会用到@来装饰函数.当时查了资料,大致了解装饰器一般用于在不改变原函数的基础上 ,对原函数功能进行修改/增强.使用场景是:日志级别设置.权限校验.性能测试等. ...

  7. python高阶函数闭包装饰器_Python_基础_(装饰器,*args,**kwargs,高阶函数,函数闭包,函数嵌套)...

    一,装饰器 装饰器:本质就是函数,功能是为其它的函数动态添加附加的功能 原则:对修改关闭对扩展开放 1.不修改被修饰函数的源代码 2.不修改被修改函数的调用方式 装饰器实现的知识储备:高阶函数,函数嵌 ...

  8. SIGIA_4P python学习 列表 字典 集合 面对对象编程 闭包 装饰器 函数式编程 作用域 异常处理

    SIGIA_4P python学习 列表 字典 集合 面对对象编程 闭包 装饰器 函数式编程 作用域 异常处理 本文连接 简介 SIGIA_4P 网址 a. 课程OKR Objectives and ...

  9. python中的装饰器(基础装饰器)

    文章目录 一 前置知识-高阶函数,闭包 1. 高阶函数 2. 闭包 二 函数装饰器 1. 什么是装饰器(原理)? 2. 装饰器的实现 3. 何时执行装饰器 4. wraps方法 三 类装饰器 一 前置 ...

最新文章

  1. 20年后,机器人有望“上手术台”啦
  2. Java锁有哪些种类,以及区别
  3. Objective-C中,ARC下的 strong和weak指针原理解释
  4. 【软件测试】黑盒测试の等价类划分法
  5. 故宫学生网页设计作品 dreamweaver作业静态HTML网页设计模板 旅游景点网页作业制作
  6. ultrascale和arm区别_UltraScale+MPSoC软硬件设计及入门套件
  7. 基于【国基北盛】云基础架构平台软件搭建openstack私有云平台(先电V2.4版本)
  8. 如何通俗理解圣维南原理?
  9. 企业项目管理八大经典法宝
  10. F12修改服务器数据,网页f12查看服务器
  11. gigaset812说明书_西门子GIASET825电话机说明书.pdf
  12. JVM: PermGen space
  13. 苹果电容笔和普通电容笔有什么区别?实用平板电脑电容笔推荐
  14. uva11689 Soda Surpler
  15. tomcat管理界面登录无法进入
  16. leaflet调用2019天地图接口
  17. SpringBoot发现静态文件加载失败的问题
  18. Android关于drawable和drawable-v24,mipmap-anydpi-v26引起的java.lang.NullPointerException
  19. 更新Linux网卡驱动
  20. html表格里怎么让字分行,excle文字怎么换行 | Excel单元格里文字如何分行

热门文章

  1. 我来了,新鲜活人报道。
  2. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---20
  3. Offer是否具有法律效力?
  4. [VS2010]在C#工程中设置Reference的相对路径
  5. 优化JavaScript代码
  6. android 图片在哪里设置时间,android 按时间显示图片
  7. acwing算法题--直方图中最大的矩形
  8. 定题信息服务是从什么角度_格木教育谢浩浩:事业单位综合应用概念分析题之角度界定技巧...
  9. c语言程序段的流程图怎么画,大家帮我看看这个程序的流程图怎么画,谢了
  10. 公网开放的plc设备——一种新型的后门