开发者学堂课程【Python Web 开发基础:Response 使用及 Wsgify 装饰器】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/554/detail/7639
Response 使用及 Wsgify 装饰器
Environ 的解析— — webob 库
环境数据有很多,都是存在字典中的,字典的存取方式没有对象的属性访问方便。使用第三方库 webob ,可以把环境数据的解析、封装成对象。
(1)Webob.Request 对象
将环境参数解析并封装成 request 对象
GET 方法,发送的数据是 URL 中 Query string,在 Request Header 中。 request.GET 就是一个字典 MultiDict,里面就封装着查询字符串。
POST 方法,"提交"的数据是放在 Request Body 里面,但是也可以同时使用 Query String。Request.POST 可以获取 Request Body 中的数据,也是个字典 MultiDict。
(2)MultiDict
MultiDict 允许一个 key 存了好几个值。
from webob.multidict import MultiDict
md=MultiDict()
md.add(1,'magedu')
md.add(1,'.com')
md.add('a',1)
md.add('a',2)
md.add('b', '3')
md['b'] = '4'
for pair in md.items():
print(pair)
print(md.getall(1))
#print(md.getone('a'))#只能有一个值
print(md.get('a'))#返回一个值
print(md.get('c'))#不会抛异常KeyError,返回None
(3)Webob.Response 对象
res = webob.Response()
print(res.status)
print(res.headerlist)
start_response(res.status,res.headerlist)
#返回可迭代对象
html='
马哥教育欢迎你
'.encode("utf-8")
return [html]
如果一个 Application 是一个类的实例,可以实现 _call_ 方法。
我们来看看 webob.Response 类的源代码
def _call_ (self,environ, start_response):
“ “ ”
WSGI application interface
“ “ ”
if self.conditional_response:
return self.conditional_response_app(environ,start_ response)
headerlist=self. _abs_headerlist(environ)
Start_response(self.status,headerlist)
if environ ['REQUEST_METHOD'] =='HEAD':
# Special case here...
return EmptyResponse(self. _app_iter)
return self. _app_iter
由此可以得到下面代码
def application(environ:dict,start_response):
#请求处理
request=webob.Request(environ)
print(request.method)
print(request.path)
print(request.query_string)
print(request.GET)
print(request.P0ST)
print('params ={}'.format(request.params))
#响应处理
res=webob.Response()#[('Content-Type','text/html;charset=UTF-8'),('Content-Length','0')]
res.status_code=200#默认200
print(res.content_type)
html='
马哥教育欢迎你
'.encode("utf-8") res.body=html
return res(environ, start_response)
(4)Webob.dec 装饰器
Wsgify 装饰器
class webob.dec.wsgify(func=None,RequestClass=None,args=(), kwargs=None,middleware_wraps=None)
from webob.dec import wsgify
@wsgify
def app(request:webob.Request)->webob.Response:
res=webob.Response('
马哥教育欢迎你.magedu.com
')
return res
Wsgify 装饰器装饰的函数应该具有一个参数,这个参数是 webob.Request 类型,是对字典 environ 的对象化后的实例。
返回值
可以是一个 webob.Response 类型实例
可以是一个 bytes 类型实例,它会被封装成 webob.Response 类型实例的 body 属性
可以是一个字符串类型实例,它会被转换成 bytes 类型实例,然后会被封装成 webob.Response 类型实例的 body 属性
总之,返回值会被封装成 webob.Response 类型实例返回
将上面的 app 函数封装成类
from webob import Response, Request
from webob.dec import wsgify
from wsgiref.simple_server import make_server
class App:
@wsgify
def_call_(self,request:Request):
return '
马哥教育欢迎你.magedu.com
'
if _name_=='_main_ ':
ip='127.0.0.1'
port =9999
server =make_server(ip,port, app)
try:
server.serve_forever()# server.handle_request()一次
except KeyboardInterrupt:
server.shutdown()
server.server_close()
上面代码中,所有的请求,都有这个 App 类的实例处理,需要对它进行改造。