python中装饰器的原理以及实现,

python版本 3.6

1.python的装饰器说白了就是闭包函数的一种应用场景,在运用的时候我们遵循

#开放封闭原则:对修改封闭,对拓展开放

2.什么是装饰器

#装饰他人的器具,本身可以是任意可调用的对象,被装饰者也可以是任意可调用对象
#装饰器的原则:1.不可修改被装饰对象的源代码,2不修改被装饰对象的调用方式
#装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

3.实现装饰器之前先来了解闭包函数

#1.闭包函数 => 函数嵌套+函数对象+名称空间与作用域
#闭:定义是在函数内的函数
#包:该内部函数需要访问一个名字,该名字是属于外层函数作用域的

#闭包函数实现的基本模板

def outter(xxx):
     def inner()
           xxx
      return inner

#为函数体传参的两个方案
#1.直接传入参数
#2.在函数体内部定义变量

4.装饰器的实现

#阶段一
#计算一个函数执行的时间

import time
def index():
      time.sleep(1)
      print("welcome to my world")

start = time.time()
index()
end = time.time()
print("run time is %s" %(end - start))
#修改了装饰对象的源代码

#阶段二
import time
def index():
      time.sleep(1)
      print("welcome to my world")

def wrapper():
      start = time.time()
      index()
      end = time.time()
      print("run time is %s" %(end - start))
#修改了装饰对象的调用方式

#阶段三
import time
def index():
      time.sleep(1)
      print("welcome to my world")

def wrapper(func):
      start = time.time()
      func()
      end = time.time()
      print("run time is %s" %(end - start))
wrapper(index)
#修改了装饰对象的调用方式

#阶段四:
import time

def index():
    time.sleep(1)
    print('welcome to index page')

def timmer(func):
    # func=最原始那个index的内存地址
    def wrapper():
        start=time.time()
        func()
        stop=time.time()
        print('run time is %s' %(stop - start))
    return wrapper
#把函数作为参数传进去,返回一个函数再去执行,替换返回的函数名为之前传入的函数 
index=timmer(index) #index=wrapper的内存地址
index() #wrapper()
#这样就没有修改被装饰对象的源代码和调用方式

5.装饰器语法糖

#装饰器语法糖
#在被装饰器对象上方单独一行写:@装饰器的名称
解释器一旦执行到@装饰器的名字就会执行 原函数名 = 装饰器的名字(正下方的那个函数)

#修订之后的装饰器
import time

def timmer(func):
    # func=最原始那个index的内存地址
    def wrapper(*args,**kwargs):
        start=time.time()
res
=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop - start)) return res return wrapper @timmer #index=timmer(最原始那个index的内存地址) #index=wrapper的内存地址 def index(): time.sleep(1) print('welcome to index page') index()

6.完善装饰器

#装饰器实现函数,其函数对象的变化,其中包括一些内置的方法__name__,__doc__等等,
#这些都是要在被装饰之后返回同样的name,doc
下面我们引入一个第三方包 去实现这些功能
import time
from functools import wraps

def timmer(func):
    @wraps(func)
    def wrapper(*args,**kwargs):
        start=time.time()
        #函数返回值
        res=func(*args,**kwargs)
        stop=time.time()
        print('run time is %s' %(stop - start))
        return res
    # wrapper.__doc__=func.__doc__
    # wrapper.__name__=func.__name__
    return wrapper

# @timmer #index=timmer(最原始那个index的内存地址) #index=wrapper的内存地址
def index():
    """
    这是一个index函数
    :return:
    """
    time.sleep(1)
    print('welcome to index page')
#上面的引入的第三方包wraps,调用其装饰器帮我们实现了
    # wrapper.__doc__=func.__doc__
    # wrapper.__name__=func.__name__ 等等这些功能,这样能更好的满足用户的需求

7.上面实现的装饰器是无参装饰器,有参装饰器更新中…………

猜你喜欢

转载自www.cnblogs.com/zj901203/p/9984028.html