• 14 Python 装饰器


    装饰器

      装饰器其实就是一个以函数作为参数并返回一个替换函数的可执行函数。让我们从简单的开始,直到能写出实用的装饰器。

     1 def outer(some_func):
     2     def inner():
     3         print "before some_func"
     4         ret = some_func() # 1
     5         return ret + 1
     6     return inner
     7 def foo():
     8     return 1
     9 decorated = outer(foo) # 2
    10 decorated()
    11 
    12 before some_func
    13 2
    View Code

    装饰器的形成过程

     1 import time
     2 
     3 def func1():
     4     print('in func1')
     5 
     6 def timer(func):
     7     def inner():
     8         start = time.time()
     9         func()
    10         print(time.time() - start)
    11     return inner
    12 
    13 func1 = timer(func1)
    14 func1()
    View Code

      装饰器—语法糖

     1 import time
     2 def timer(func):
     3     def inner():
     4         start = time.time()
     5         func()
     6         print(time.time() - start)
     7     return inner
     8 
     9 @timer   #==> func1 = timer(func1)
    10 def func1():
    11     print('in func1')
    12 
    13 
    14 func1()
    View Code

      装饰器的本质:一个闭包函数

      装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

      装饰器—带参数的装饰器

     1 def timer(func):
     2     def inner(a):
     3         start = time.time()
     4         func(a)
     5         print(time.time() - start)
     6     return inner
     7 
     8 @timer
     9 def func1(a):
    10     print(a)
    11 
    12 func1(1)
    View Code

      装饰器—成功hold住所有参数的装饰器

     1 import time
     2 def timer(func):
     3     def inner(*args,**kwargs):
     4         start = time.time()
     5         re = func(*args,**kwargs)
     6         print(time.time() - start)
     7         return re
     8     return inner
     9 
    10 @timer   #==> func1 = timer(func1)
    11 def func1(a,b):
    12     print('in func1')
    13 
    14 @timer   #==> func2 = timer(func2)
    15 def func2(a):
    16     print('in func2 and get a:%s'%(a))
    17     return 'fun2 over'
    18 
    19 func1('aaaaaa','bbbbbb')
    20 print(func2('aaaaaa'))
    View Code

      装饰器—带返回值的装饰器

     1 import time
     2 def timer(func):
     3     def inner(*args,**kwargs):
     4         start = time.time()
     5         re = func(*args,**kwargs)
     6         print(time.time() - start)
     7         return re
     8     return inner
     9 
    10 @timer   #==> func1 = timer(func1)
    11 def func1(a,b):
    12     print('in func1')
    13 
    14 @timer   #==> func2 = timer(func2)
    15 def func2(a):
    16     print('in func2 and get a:%s'%(a))
    17     return 'fun2 over'
    18 
    19 func1('aaaaaa','bbbbbb')
    20 print(func2('aaaaaa'))
    View Code

    开放封闭原则

      1.对扩展是开放的

        为什么要对扩展开放呢?

        我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

      2.对修改是封闭的

        为什么要对修改封闭呢?

        就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

      装饰器完美的遵循了这个开放封闭原则。

    装饰器的主要功能和装饰器的固定结构

      装饰器的主要功能:

        在不改变函数调用方式的基础上在函数的前、后添加功能。

      装饰器的固定格式:

    1 def timer(func):
    2     def inner(*args,**kwargs):
    3         '''执行函数之前要做的'''
    4         re = func(*args,**kwargs)
    5         '''执行函数之后要做的'''
    6         return re
    7     return inner
    View Code

    带参数的装饰器

     1 def outer(flag):
     2     def timer(func):
     3         def inner(*args,**kwargs):
     4             if flag:
     5                 print('''执行函数之前要做的''')
     6             re = func(*args,**kwargs)
     7             if flag:
     8                 print('''执行函数之后要做的''')
     9             return re
    10         return inner
    11     return timer
    12 
    13 @outer(False)
    14 def func():
    15     print(111)
    16 
    17 func()
    View Code

    多个装饰器装饰同一个函数

     1 def wrapper1(func):
     2     def inner():
     3         print('wrapper1 ,before func')
     4         func()
     5         print('wrapper1 ,after func')
     6     return inner
     7 
     8 def wrapper2(func):
     9     def inner():
    10         print('wrapper2 ,before func')
    11         func()
    12         print('wrapper2 ,after func')
    13     return inner
    14 
    15 @wrapper2
    16 @wrapper1
    17 def f():
    18     print('in f')
    19 
    20 f()
    View Code
  • 相关阅读:
    在ASP.NET开始执行HTTP请求的处理程序之前
    要在一般处理程序中获取其他页面的session值
    asp.net中session的原理及应用
    INTRAWEB说明书
    ASP.NET万能JSON解析器
    使用 IntraWeb (30)
    IntraWeb例子练习
    【整理】Asp.net HttpWebRequest和HttpWebResponse发送和接受任何类型数据
    Delphi 接口机制真相
    http://www.doc88.com/p-203939126010.html
  • 原文地址:https://www.cnblogs.com/panfb/p/7811647.html
Copyright © 2020-2023  润新知