一、装饰器原理
'''
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