zoukankan      html  css  js  c++  java
  • 装饰器

    2.【理解】闭包的概念和基本使用

    • 闭包的作用:保证外层函数调用后,外层函数的变量不会销毁。

    • 闭包构成的条件:

        1. 函数嵌套的前提下

        2. 内层函数使用外层函数的变量

        3. 外层函数返回内层函数名

    • 基本使用:

      # 外层函数: 有一个参数叫num1
      def func_out(num1): # num1 = 100

      # 1.在函数嵌套的前提下
      # 内层函数:有一个参数叫num2
      def func_inner(num2):  # 使用外部函数变量的内部函数称为闭包。
          # 2.内部函数使用了外部函数的变量(num1)
          result = num1 + num2
          print(result)

      # 3.并且外部函数返回了内部函数,
      return func_inner


      if __name__ == '__main__':
      # 闭包对象
      f = func_out(100)  # f = func_inner

      f(100)
      f(200)

    3.【理解】闭包的应用

    • 实现步骤说明

      • 定义外部函数接收不同的配置信息参数,参数是人名

      • 定义内部函数接收对话信息参数

      • 在内部函数里面把配置信息和对话信息进行拼接输出


    # 需求: 根据配置信息使用闭包实现不同人的对话信息,例如对话:
    #
    # 张三: 到北京了吗?
    # 李四: 已经到了,放心吧。


    def config_name(name):  # name='张三' name='李四'

       # 闭包
       def say_info(info):
           print(name + ":" + info)

       return say_info

    if __name__ == '__main__':

       zs = config_name("张三")      # zs = say_info

       zs("在吗?")
       zs("到深圳了吗?")

       ls = config_name("李四")      # ls = say_info
       ls('不在')
       ls('不和你玩')

       zs('我请客,吃鸡')
       ls('敲完代码先')

    4.【了解】闭包中变量问题

    • 内层定义了和外层同名的变量

      重新在内层函数中定义了新的变量

    • 解决办法:nonlocal num1

      def func_out(num1):

      def func_inner(num2):
        # 声明使用外部函数变量num1
        nonlocal num1

        num1 = 10
        result = num1 + num2
        print(result)

      print(num1)
      func_inner(1)
      print(num1)

      return func_inner


      if __name__ == '__main__':
      f = func_out(1)

      f(2)
      f(3)

       

    5.【理解】装饰器入门

    • 装饰器的作用:在不改变源代码和源代码调用方式的基础上,增加新的功能;

    • 装饰器使用:

      1) 待装饰函数=装饰器(待装饰函数)

      2)@装饰器

    • 写法:

      def func_out(fn):

      def inner():
        print("请先登录....")
        fn()
       
      return inner

      # 2.使用语法糖装饰
      @func_out
      def comment():
      print("发表评论....")


      # 1.使用装饰器装饰原函数
      # comment = func_out(comment)
      if __name__ == '__main__':
      comment()

    6.【应用】装饰器的使用

    • 装饰器实现已有函数执行时间的统计


      # 使用装饰器统计函数的执行时间
      import time


      def get_time(fn):

      def inner():
          start = time.time()
          fn()
          end = time.time()
          print("执行函数花费时间: ", end - start)

      return inner


      @get_time
      def func1():
      for i in range(100000):
          print(i)


      if __name__ == '__main__':
      func1()

    7.【应用】通用装饰器

    • 普通参数


      def func_out(fn):   # fn = func

      def inner(name):
          print("请先登录...")
          fn(name)        # func(name)

      return inner


      @func_out       # func=func_out(func) # func=inner
      def func(name):
      print(name, ":发表评论...")


      if __name__ == '__main__':
      func("小明")  # inner("小明")

    • 可变参数


      def func_out(fn):   # fn = func

      def inner(*args, **kwargs):
          print("请先登录...")
          fn(*args, **kwargs)        # func(name)

      return inner


      @func_out
      def func(*args, **kwargs):
      print(args)
      print(kwargs['name'], ":发表评论...")


      if __name__ == '__main__':
      func(1,2,3,4,name="小明")
    • 有返回值

      # 内层函数的结构应该和待装饰函数的结构一样


      def func_out(fn):   # fn = func

      def inner(name):    # name="小明"
          print("请先登录...")
          result = fn(name)        # result = func(name)
          return result

      return inner


      @func_out       # func=func_out(func)   # func=inner
      def func(name):
      print(name, ":发表评论...")
      return 100


      if __name__ == '__main__':
      value = func("小明")          # value = inner("小明")
      print("返回值:", value)
    • 通用装饰器

      • 作用:可以装饰不定长参数的函数和有返回值的函数。

      • 格式:


      # 通用装饰器
      def func_out(fn):

         def inner(*args, **kwargs):
             print("请先登录...")
             result = fn(*args, **kwargs)
             return result

         return inner
    • 使用:

      @func_out
      def func(*args, **kwargs):
         print(args)
         print(kwargs['name'], ":发表评论...")

         return 100


      @func_out
      def func2(name):
         print(name, ":发表评论...")


      @func_out
      def func3(name):
         print(name, ":发表评论...")
         return 100

    8.【理解】多重装饰器

    • 多重装饰器:一个函数被多个装饰器装饰

    • 装饰原则:

      多个装饰器可以对函数进行多个功能的装饰,装饰顺序是由内到外的进行装饰,调用顺序正好相反。

    9.【应用】带有参数的装饰器

    • 语法格式:

      # 带有参数的装饰器 (装饰器工厂函数)
      def logging(flag):

      def decroator(fn):
          def inner(n1, n2):
              if flag == "+":
                  print("正在努力运行加法运行...")
              elif flag == "-":
                  print("正在努力运行减法法运行...")
              result = fn(n1, n2)
              return result
          return inner

      # 返回装饰器
      return decroator
    • 使用方法:

    • @logging("+")       #解释器执行的顺序 1.logging("+") 2.@decroator
      def add(a, b):
      result = a + b
      return result


      @logging("-")       #解释器执行的顺序 1.logging("-") 2.@decroator
      def sub(a, b):
      result = a - b
      return result

    10.【了解】类装饰器

    • 作用:使用类来实现闭包效果, 进行装饰

    • 类的书写:

      必须有两个方法

      1) __init__(self, fn)

      2)__call__(self, *args, **kwargs)


      # 类装饰器
      class func_out(object):

         def __init__(self, fn):     # fn = comment
             self.__fn = fn

         def __call__(self, *args, **kwargs):
             print("请先登录...")
             self.__fn()


      @func_out   # comment=func_out(comment) # comment是func_out类的对象.
      def comment():
         print("发表评论...")

  • 相关阅读:
    问题大全
    redis学习笔记-03:redis安装
    redis学习笔记-02:为什么使用NoSQL数据库
    redis学习笔记-01:redis简介
    docker学习笔记-05:Docker安装mysql和redis
    docker学习笔记-06:自定义DockerFile生成镜像
    docker学习笔记-05:DockerFile解析
    全栈之路-杂篇-JPA多对多配置分析
    全栈之路-小程序API-JWT令牌详细剖析与使用
    全栈之路-小程序API-Json数据类型的序列化与反序列化
  • 原文地址:https://www.cnblogs.com/zhangwei112/p/13586793.html
Copyright © 2011-2022 走看看