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

    一 什么是装饰器

    装饰器定义:本质就是函数,功能是为其他函数添加新功能

    二 装饰器需要遵循的原则

    1.不修改被装饰函数的源代码(开放封闭原则)

    2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

    三 实现装饰器知识储备

    装饰器=高阶函数+函数嵌套+闭包

    给函数加多个装饰器,先执行最下面的装饰器

    四 高阶函数

    高阶函数定义:
    1.函数接收的参数是一个函数名

    2.函数的返回值是一个函数名

    3.满足上述条件任意一个,都可称之为高阶函数

    #高阶函数应用1:把函数当做参数传给高阶函数
    import time
    def foo():
        print('from the foo')
    
    def timmer(func):
        start_time=time.time()
        func()
        stop_time=time.time()
        print('函数%s 运行时间是%s' %(func,stop_time-start_time))
    timmer(foo)
    #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
    #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
    import time
    def foo():
        print('from the foo')
    
    def timmer(func):
        start_time=time.time()
        return func
        stop_time=time.time()
        print('函数%s 运行时间是%s' %(func,stop_time-start_time))
    foo=timmer(foo)
    foo()
    #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能

    高阶函数总结
    1.函数接收的参数是一个函数名
      作用:在不修改函数源代码的前提下,为函数添加新功能,
      不足:会改变函数的调用方式
    2.函数的返回值是一个函数名
      作用:不修改函数的调用方式
      不足:不能添加新功能

    五 函数嵌套

    def f1():   
    print('------>f1 ',x)
    def f2():
    print('---->f2 ',x)
    def f3():
    print('-->f3 ',x)
    f3()
    f2()

    f1()

    六 闭包

    def f1(x):
    x=1000
    def f2():
    print(x)
    return f2
    f=f1(10) #结果是内部的f2的内存地址

    七 无参装饰器

    无参装饰器=高级函数+函数嵌套

    基本框架

     #这就是一个实现一个装饰器最基本的架子
     def timer(func):
         def wrapper():
             func()
         return wrapper

    加上参数 

     def timer(func):  #参数是被装饰的函数
     
    def wrapper(*args,**kwargs): #参数是被装饰函数的参数
    func(
    *args,**kwargs) return wrapper

    加上功能

     import time
     def timer(func):
         def wrapper(*args,**kwargs):
             start_time=time.time()
             func(*args,**kwargs)
             stop_time=time.time()
             print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
        return wrapper

    加上返回值

     import time
     def timer(func):
         def wrapper(*args,**kwargs):
             start_time=time.time()
             res=func(*args,**kwargs) #被装饰函数有返回值,才res
             stop_time=time.time()
             print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
             return res
         return wrapper

    使用装饰器语法糖@

     @timer  #@timer就等同于cal=timer(cal)
     def cal(array):
         res=0
         for i in array:
             res+=i
         return res
     
     cal(range(10))

    八 有参装饰器

    有参装饰器和执行步骤

    def auth2(auth_type):  #1   #3
        def auth(func):     #4   #6
            def wrapper(*args,**kwargs):  #7   #10
                if auth_type == 'file':
                    name=input('username: ')
                    password=input('password: ')
                    if name == 'zhejiangF4' and password == 'sb945':
                        print('auth successfull')
                        res=func(*args,**kwargs)
                        return res
                    else:
                        print('auth error')
                elif auth_type == 'sql':
                    print('还他妈不会玩')
            return wrapper      #8
        return auth     #5
    
    @auth2(auth_type='sql') #@auth  #index=auth(index)    #2
    def index():
        print('welcome to inex page')
    
    index()   #9   相当于运行wrapper()

     7、多个装饰器的执行顺序

    def one(func):
        print('----1----')
        def two():
            print('----2----')
            func()
        return two
    
    def a(func):
        print('----a----')
        def b():
            print('----b----')
            func()
        return b
    
    @one
    @a
    def demo():
        print('----3----')
    
    demo()
    执行结果:
    
    /usr/bin/python2.7 /home/python/Desktop/tornadoProject/one.py
    ----a----
    ----1----
    ----2----
    ----b----
    ----3----
  • 相关阅读:
    MVC4笔记 @functions @model @using
    NET平台4.0 发布网站流程及出错总结
    C#读写txt文件的方法
    jQuery Validate验证框架详解(转)
    用C#写的读写CSV文件
    devexpress 数据导入(gridcontrol 导出 csv)
    DevExpress XtraGrid 数据导出导入Excel
    DevExpress 表中数据导出
    DevExpress 重编译 替换强命名 修改源码
    Delphi 的运算符列表
  • 原文地址:https://www.cnblogs.com/domestique/p/6752486.html
Copyright © 2011-2022 走看看