一、装饰器原理
‘‘‘
javascript Python 面向对象编程 一切皆对象 函数为闭包函数,可以将函数名赋值给变量 ‘‘‘ def hi(name = "yasoob"): return "hi" + name print(hi()) #output:"hi yasoob" #我们甚至可以将一个函数赋值为一个变量,比如 greet = hi ‘‘‘ 在函数中定义函数 ‘‘‘ def hi(name = "yasoob"): print("now you are inside the hi() function") def greet(): return "now you are in the greet() function" def welcome(): return "now you are in the welcome() function" print(greet()) print(welcome()) hi() ‘‘‘ 从函数中返回函数 这样就可以把函数中定义的函数返回出来 ‘‘‘ print("*"*20) def hi(name = "yasoob"): def greet(): return "now you are in the greet() function" def welcome(): return "now you are in the welcome() function" if name == "yasoob": return greet else: return welcome a = hi() print(a()) print(‘*‘*50) """ 将函数名作为一个参数传给另一个参数 """ def hi(): return "hi yasoob!" def doSomethingBeforeHi(func): print("I am doing some boring work before executing hi()") print(func()) doSomethingBeforeHi(hi) print(‘开始第一个装饰器‘) ‘‘‘ 开始第一个装饰器 ‘‘‘ def a_new_decorator(a_func): def wrapTheFunction(): print("I am doing some boring work before executing a_fun()") a_func() print("I am doing some boring work agter executing a_fun()") return wrapTheFunction def a_function_requiring_decoration(): print("I am the function which needs some decoration to remove my foul smell") a_new_decorator(a_function_requiring_decoration)() print(‘使用@定义的装饰器‘) ‘‘‘ 使用@定义的装饰器,但是这里进行更改了注释的文档 需要用functools.wraps来修改注释文档 ‘‘‘ @a_new_decorator def a_function_requore_decoration():
""" Hey you! Decorate me!!!""" print("I am the function which needs some decoration to remove my foul smell") print(a_new_decorator(a_function_requore_decoration)())
二、装饰器实现
from functools import wraps def a_new_decorator(a_func): @wraps(a_func) def wrapTheFunction(): print("I am doing some boring work before executing a_func()") a_func() print("I am doing some boring work before executing a_func()") return wrapTheFunction @a_new_decorator def a_function_requiring_decoration(): print("I am the function which needs some decoration to remove my foul smell") print(a_function_requiring_decoration()) print("*/"*50) ‘‘‘ 开始装饰器的蓝本---控制函数是否运行 ‘‘‘ from functools import wraps def decorator_name(f): @wraps(f) def decorated(*args,**kwargs): if not can_run: return "Function will not run" return f(*args,**kwargs) return decorated @decorator_name def func(): return ("Function is runing") can_run = True print("can_run = True\t\t\t",func()) can_run = False print("can_run = False\t\t\t",func()) ‘‘‘ 检查一个人是否被授权使用一个web的端点 被大量用于Flask 和Django web框架中 ‘‘‘ from functools import wraps import requests def require_auth(f): @wraps(f) def decorated(*args,**kwargs): auth = requests.agthorization if auth or not check_auth(auth.username,auth.password): pass return f(*args,**kwargs) return decorated def check_auth(): pass ‘‘‘ 日志中的装饰器 ‘‘‘ from functools import wraps def logit(func): @wraps(func) def with_logging(*args,**kwargs): print(func.__name__+"was called") return func(*args,**kwargs) return with_logging ‘‘‘ 带参数的装饰器 ‘‘‘ from functools import wraps import logging def logit(logfile = "out.log"): def logging_decorator(func): @wraps(func) def wrapped_function(*arg,**kwargs): log_string = func.__name__ + "was called" print(log_string) with open(logfile,"a") as opened_file: opened_file.write(log_string + ‘\n‘) return func(*arg,**kwargs) return wrapped_function return logging_decorator @logit() def myfunc1(a=3,b=4): print(a*b) myfunc1(5,6) ‘‘‘ 以类的形式重构logit装饰器 ‘‘‘ print(‘以类的形式重构logit装饰器‘,‘*‘*60) from functools import wraps class logit(object): def __init__(self,logfile = "out.log"): self.logfile = logfile def __call__(self, *args, **kwargs): @wraps(func) def wrapped_function(*args,**kwargs): log_string = func.__name__ + "was called" print(log_string) with open(self.logfile,"a") as opened_file: opened_file.write(log_string) self.notify() return func(*args,**kwargs) return wrapped_function def notify(self): pass @logit() def myfunc1(): pass class email_logit(logit): def __init__(self,email = "admin@myproject.com",*args,**kwargs): self.email = email super(email_logit,self).__init__(*args,**kwargs) def notefy(self): pass