day063--装饰器
1.装饰器
装饰器:在不改变原函数的调用方式和函数,额外的增加功能
-
简单装饰器
def timer(func):
def inner():
print(time.time())
func() # 原来的函数
return inner@timer # func1 = timer(func1)
def func1():
print('func1') -
函数带返回值
def timer(func):
def inner():
print(time.time())
ret = func() # 原来的函数
return ret
return inner -
原函数携带参数
def download(func):
def inner(args, **kwargs):
print('下载软件')
func(args, **kwargs)
return inner -
完整的装饰器的写法
def wrapper(func):
def inner(args, **kwargs):
# 执行被装饰函数之前进行的操作
ret = func(args, **kwargs)
# 执行被装饰函数之后进行的操作
return ret
return inner -
装饰器带参数
def outer(flag):
def timer(func):
def inner(args, **kwargs):
if flag:
print(time.time())
ret = func(args, **kwargs) # 原来的函数
else:
ret = func(*args, **kwargs) # 原来的函数
return ret
return inner
return timer@outer(True) # func1 = timer(func1) inner
def func1():
print('func1') -
多个装饰器装饰同一个函数
def wrapper1(func):
def inner(args, **kwargs):
print('wrapper1 前') # 2
ret = func(args, **kwargs)
print('wrapper1 后') # 4
return ret
return innerdef wrapper2(func):
def inner(args, **kwargs):
print('wrapper2 前') # 1
ret = func(args, **kwargs)
print('wrapper2 后') # 5
return ret
return inner@wrapper2 # func1 = wrapper2(func1) wrapper2.inner func=wrapper1.inner
@wrapper1 # func1 = wrapper1(func1) wrapper1.inner func=func1
def func1():
print('func1') # 3
return 'func1的返回值'print(func1()) # 6
-
装饰器修复技术
from functools import wraps
def timer(func):
@wraps(func)
def inner():
print(time.time())
ret = func() # 原来的函数
return ret
return inner@timer
def func1():
'''
这里是func1
:param x:
:param y:
:return:
'''
return 111print(func1.name) # 不修复显示inner, 修复后显示func1
print(func1.doc) # 不修复显示none, 修复后显示func1的文档带参数和修复的装饰器
from functools import wraps
def outer(flag):
def wrapper(func):
@wraps(func)
def inner(args, **kwargs):
if flag:
print("装饰器启动了")
else:
print("没有启动装饰器!!!")
ret = func(args, **kwargs)
return retreturn inner return wrapper@outer(0)
def hello():
"""
:param
:return:
"""
print("hello")hello()
print(hello.name)
print(hello.doc)
2.视图系统
-
CBV和FBV
-
FBV(function based view )
-
CBV(class based view)
-
定义
# 增加出版社 CBV
from django.views import Viewclass AddPublisher(View): def get(self, request): pass def post(self, request): pass -
使用
url(r'^add_publisher/', views.AddPublisher.as_view()),
-
-
CBV的流程
-
views.AddPublisher.as_view() 程序加载的时候执行 ——》 view函数 - 当请求到来的时候执行view函数:
- self = AddPublisher()
- self.request = request
- 执行self.dispatch方法
- 判断请求方式是否被允许
- 允许时,通过反射获取到AddPublisher中定义的get或者post方法 ——》handler
- 不允许时,self.http_method_not_allowed ——》handler
- 执行handler 拿到返回结果 Httpresponse对象
- 判断请求方式是否被允许
-
-
给CBV加装饰器
from django.utils.decorators import method_decorator- 加载某个get/post的方法上:
@method_decorator(timer)
def get(self, request): - 加在self.dispatch方法上(***推荐):需要自己定义dispatch方法
@method_decorator(timer)
def dispatch(self, request, *args, **kwargs):
super().dispatch(request, *args, **kwargs) - 加在类上:
@method_decorator(timer, name='post')
@method_decorator(timer, name='get')
class AddPublisher(View):
- 加载某个get/post的方法上:
-
区别
- 不使用method_decorator
先收到self,第二个参数是request
func: <function AddPublisher.dispatch at 0x00000163735176A8>
args :<app01.views.AddPublisher object at 0x00000163735F7EF0> <WSGIRequest: GET '/add_publisher/'> - 使用method_decorator
直接绑定某个对象,不用传self, 直接收到request
所以如果想用request,就是用此方法,直接拿第一个参数就是request
func:<function method_decorator..dec. .wrapper. .bound_func at 0x0000019664B4A378>
arsgs: <WSGIRequest: GET '/add_publisher/'>
- 不使用method_decorator
-
request
print(request.method) # GET 请求反方式
print(request.GET) # {} [] get()
print(request.POST) # {} [] get()
print(request.FILES)
print(request.path_info,type(request.path_info)) # 路径信息 不包含IP和端口、参数print(request.get_host())
print(request.get_full_path()) # 路径信息 + 参数
上传文件注意事项:
1. form表单的enctype = 'multipart/form-data'
2. request.FILES中获取文件对象
3. 使用文件对象的chunks()
```python
def upload(request):
if request.method == "POST":
# print(request.body)
file1 = request.FILES
print(file1)
file = file1.get('f1')
print(file, file.name, type(file.name))
with open(file.name, 'wb') as f:
# 将文件一点点读取,写入文件
for chunk in file.chunks():
f.write(chunk)
return HttpResponse('上传成功!')
return render(request, 'upload.html')
```
3.JsonResponse
from django.http import JsonResponse
def json_test(request):
data = {'name': 'alex', 'pwd': 'alexdsb'}
return JsonResponse(data) # Content-Type: application/json
# return HttpResponse(json.dumps(data), content_type='application/json') # Content-Type: text/html; charset=utf-8

浙公网安备 33010602011771号