装饰器
一、python装饰器
1、简易装饰器(无参数,无返回值)
def decorator01(func):
def neweat():
print('饭前先洗手 (原函数before执行....)')
func()
print('饭后百步走 (原函数after执行.....)')
return neweat
@decorator01
def eat(): # 原函数
print('吃饭咯.. (原函数running....)')
# 调用原函数
eat()
print('被装饰后的原函数名', eat.__name__)
2、装饰器(无参数,有返回值)
from functools import wraps
def decorator02(func):
@wraps(func) # 保持原函数名称不变
def neweat():
print('饭前先洗手 before执行....')
ret = func()
print('饭后百步走 after执行.....')
return ret
return neweat
@decorator02
def eat(): # 原函数
print('吃饭咯.. 原函数running....')
return '好饱'
# 调用原函数
result = eat()
print('原函数的返回值为:', result)
print(eat.__name__)
3、装饰器(有参数,有返回值)
from functools import wraps
def decorator03(a):
def decorator(func):
@wraps(func)
def wrapped_function(*args, **kwargs):
b = a + '--装饰器处理后--'
ret = func(b)
return ret
return wrapped_function
return decorator
@decorator03(a='参数')
def myfunc1(b):
resp = b + '--原函数处理--'
return resp
ret = myfunc1()
print(ret)
4、类装饰器
from functools import wraps
class logit(object):
def __init__(self, logfile='out.log'):
self.logfile = logfile
def __call__(self, func):
@wraps(func)
def wrapped_function(*args, **kwargs):
log_string = func.__name__ + " was called"
print(log_string)
# 打开logfile并写入
with open(self.logfile, 'a') as opened_file:
# 现在将日志打到指定的文件
opened_file.write(log_string + '\n')
# 现在,发送一个通知
self.notify()
return func(*args, **kwargs)
return wrapped_function
def notify(self):
# logit只打日志,不做别的
pass
# 装饰
@logit()
def myfunc1():
pass
二、Django类视图使用装饰器
为类视图添加装饰器,可以使用两种方法
def my_decorator(func):
def wrapper(request, *args, **kwargs):
print('自定义装饰器被调用了')
print('请求路径%s' % request.path)
return func(request, *args, **kwargs)
return wrapper
class DemoView(View):
def get(self, request):
print('get方法')
return HttpResponse('ok')
def post(self, request):
print('post方法')
return HttpResponse('ok')
在Django类视图中使用为函数视图准备的装饰器时,不能直接添加装饰器,需要使用method_decorator
将其转换为适用于类视图方法的装饰器。
method_decorator装饰器使用 name 参数指明被装饰的方法
1、为全部请求方法添加装饰器
from django.utils.decorators import method_decorator
@method_decorator(my_decorator, name='dispatch')
class DemoView(View):
def get(self, request):
print('get方法')
return HttpResponse('ok')
def post(self, request):
print('post方法')
return HttpResponse('ok')
2、为特定请求方法添加装饰器
2.1 特定方法添加装饰(方式一)
from django.utils.decorators import method_decorator
@method_decorator(my_decorator, name='get')
class DemoView(View):
def get(self, request):
print('get方法')
return HttpResponse('ok')
def post(self, request):
print('post方法')
return HttpResponse('ok')
如果需要为类视图的多个方法添加装饰器,但又不是所有的方法(为所有方法添加装饰器参考上面例子),可以直接在需要添加装饰器的方法上使用method_decorator,如下所示
2.2 特定方法添加装饰(方式二)
from django.utils.decorators import method_decorator
class DemoView(View):
@method_decorator(my_decorator) # 为get方法添加了装饰器
def get(self, request):
print('get方法')
return HttpResponse('ok')
@method_decorator(my_decorator) # 为post方法添加了装饰器
def post(self, request):
print('post方法')
return HttpResponse('ok')
def put(self, request): # 没有为put方法添加装饰器
print('put方法')
return HttpResponse('ok')
END