zoukankan      html  css  js  c++  java
  • Python之函数(八)闭包与装饰器

    闭包

    1. 闭包

      def func():
      	a=1
      	def f1():
      		def foo():
      			print(a)
      		return foo
      	return f1
      func()()()
      ret=func() #f1函数复制给ret
      a=ret() #foo函数复制给a
      a()#调用 foo函数
      #结果为1
      #在嵌套函数内,使用非全局变量(且不是本层变量)--就是闭包
      def func():
          a=[]
          def foo(price):
              a.append(price)
              avg=sum(a)/len(a)
              return avg #返回 平均值
          return foo
      ret=func()()
      print(ret(15000))
      #结果为:15000
      print(ret.__closure__)#判断是否是闭包
      # 了解:
      # print(ret.__code__.co_freevars)  # 获取的是自由变量
      # print(ret.__code__.co_varnames)  # 获取的是局部变量
      #闭包的作用:
      #保证数据的安全性
      #装饰器
      

    4.15 装饰器

    1. 开放封闭原则

      • 此原则的基本思想是:
        • Open ( Open for extension ) 对扩展开放,模块的行为是灵活的。
        • Closed ( Closed for modification ) 对模块进行扩展的时候,不能影响已有的程序模块。
    2. 装饰器定义:在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能。

    3. 无参数版

      • def wrapper(f):
            def inner():
                f()
            return inner
        
        @wrapper
        def func():
            print(1)
        func()
        
    4. 有参数版

      • import time
        def wrapper(f):
            def inner(*args,**kwargs):
                "被装饰前"
                start_time = time.time()
                f(*args,**kwargs) # func("alex")
                print(time.time() - start_time)
                "被装饰后"
            return inner  # 切记不要加括号
        
        @wrapper  # func = wrapper(func)
        def func(*args,**kwargs):
            print(f"这是{args}函数,李业还是不行")
            time.sleep(2) #模拟网络延时
        @wrapper  # foo = wrapper(foo)
        def foo(*args,**kwargs):
            print(f"这是{args}函数,常鑫穿齐*小短裤")
            time.sleep(3) #模拟网络延时
        func("alex","sur")
        foo("alex","sur")
        
    5. 带参装饰器

      • msg = """
        1.QQ
        2.wechat
        """
        avg = input('验证方式:')
        
        def auth(avg):
            def wrapper(f):
                def inner(*args,**kwargs):
                    if avg == 'QQ':
                        user = input('name')
                        pwd = input('password')
                        if user == 'alex' and pwd == '123456':
                            f()
                        else:
                            print('输入错误')
                    elif avg == 'wechat':
                        user = input('name')
                        pwd = input('password')
                        if user == 'lfz' and pwd == '123456':
                            f()
                        else:
                            print('输入错误')
                return inner
            return wrapper
        
        @auth(avg)   #func = auth(avg)(func)
        def func():
            print(1)
            
        func()
        
      • @auth('wechat') :分两步:

        • 第一步先执行auth('wechat')函数,得到返回值auth
        • 第二步@与auth2结合,形成装饰器@auth2 然后在依次执行。
    6. 多个装饰器装饰一个函数

      • def wrapper1(func):
            def inner1(*args,**kwargs):
                print("这是装饰器一开始")
                func(*args,**kwargs)
                print("这是装饰器一结束")
            return inner1
        
        def wrapper2(func):  
            def inner2(*args,**kwargs):
                print("这是装饰器二开始")
                func(*args,**kwargs)
                print("这是装饰器二结束")
            return inner2
        
        
        @wrapper1  
        @wrapper2  
        def func():
            print("这是被装饰的函数")
        
        func()
        # 结果:
        这是装饰器一开始
        这是装饰器二开始
        这是被装饰的函数
        这是装饰器二结束
        这是装饰器一结束
        
      • Python规定多个装饰器装饰一个函数的时候先执行离被装饰的函数最近的装饰器

  • 相关阅读:
    【如何使用翻译工具翻译网页】英语没过关的可以参考下。
    HTTP 请求报文和响应报文
    VIM+ctags+cscope用法
    Ubuntu下命令行访问网站
    mini_httpd的安装和配置
    堆排序(代码2)
    插入排序
    堆排序(代码1)
    快速排序
    Python中的控制流
  • 原文地址:https://www.cnblogs.com/zhangdadayou/p/11415238.html
Copyright © 2011-2022 走看看