51web开发3_路由功能_exc_路由正则匹配-创新互联

目录

创新互联建站主营尼玛网站建设的网络公司,主营网站建设方案,app开发定制,尼玛h5小程序设计搭建,尼玛网站营销推广欢迎尼玛等地区企业咨询

ver1:...1

ver2,路由字典实现...2

ver3,将路由功能封装成类:...4

ver4,404处理,webob.exc异常:...5

ver5,注册函数改造:...7

路由正则匹配:...10

web框架开发:

route路由:

简单说,就是路怎么走,按不同的路径分发数据;

url就是不同资源的路径,不同的路径应对应不同的应用程序来处理;

所以,代码中应增加对路径的分析处理;

不管是静态web服务器,还是动态web服务器,都需要路径和资源(或处理程序)的映射,最终返回html的文本;

静态web server,解决路径和文件之间的映射;

动态web server,解决路径和应用程序之间的映射;

所有的web框架都是如此,都有路径配置;

路由功能实现:

例:

增加路由:

/   #返回欢迎内容

/python   #返回hello python

其它   #404

ver1:

例:

@dec.wsgify

def app(request):

res = Response()

if request.path == '/':

res.body = '

welcome

'.encode()

elif request.path == '/python':

res.body = '

hello python

'.encode()

else:

res.status_code = 404

res.body = 'Not Found'.encode()

return res

ver2,路由字典实现

例:

def index(request):

res = Response()

res.body = '

welcome

'.encode()

return res

def showpython(request):

res = Response()

res.body = '

hello python

'.encode()

return res

def notfound(request):

res = Response()

res.body = '

Not Found

'.encode()

return res

@dec.wsgify

def app(request):

if request.path == '/':

return index(request)

elif request.path == '/python':

return showpython(request)

else:

return notfound(request)

例:

def index(request):

res = Response()

res.body = '

welcome

'.encode()

return res

def showpython(request):

res = Response()

res.body = '

hello python

'.encode()

return res

def notfound(request):

res = Response()

res.body = '

Not Found

'.encode()

return res

route_table = {

'/': index,

'/python': showpython

}

@dec.wsgify

def app(request):

return route_table.get(request.path, notfound)(request)

例:

增加注册功能;

def index(request):

res = Response()

res.body = '

welcome

'.encode()

return res

def showpython(request):

res = Response()

res.body = '

hello python

'.encode()

return res

def notfound(request):

res = Response()

res.body = '

Not Found

'.encode()

return res

route_table = {}

def register(path, handler):

route_table[path] = handler

register('/', index)

register('/python', showpython)

@dec.wsgify

def app(request):

return route_table.get(request.path, notfound)(request)

ver3,将路由功能封装成类:

思考如何把哪些函数放到外面;

好处,封装在类里的,随着类中代码越来越多,方便之后移走,模块化;

例:

from webob import Request, Response, dec

from wsgiref.simple_server import make_server

def index(request):

res = Response()

res.body = '

welcome

'.encode()

return res

def showpython(request):

res = Response()

res.body = '

hello python

'.encode()

return res

class Application:

def notfound(self, request):

res = Response()

res.body = '

Not Found

'.encode()

return res

ROUTE_TABLE = {}   #类属性

@classmethod   #类方法和普通方法都可,最好用类方法

def register(cls, path, handler):

cls.ROUTE_TABLE[path] = handler

@dec.wsgify

def __call__(self, request:Request) -> Response:

return self.ROUTE_TABLE.get(request.path, self.notfound)(request)

Application.register('/', index)

Application.register('/python', showpython)

if __name__ == '__main__':

ip = '127.0.0.1'

port = 9999

app = Application()

# app.register('/', index)   #实例也可注册,但这样不好

# app.register('/python', showpython)

server = make_server(ip, port, app)

try:

server.serve_forever()

except KeyboardInterrupt:

pass

finally:

server.shutdown()

server.server_close()

ver4,404处理,webob.exc异常:

查看源码:

class HTTPNotFound(HTTPClientError):   #继承顺序HTTPClientError-->HTTPError-->WSGIHTTPException-->Response

code = 404

title = 'Not Found'

explanation = ('The resource could not be found.')

注:

code、title、explanation,页面展示先是这三个,再是自定义的body内容;

若要覆盖body,要在Response的__init__()中设置;

class Response(object):

def __init__(self, body=None, status=None, headerlist=None, app_iter=None,

content_type=None, conditional_response=None, charset=_marker,

**kw):

例:

class Application:

# def notfound(self, request):

#     res = Response()

#     res.body = '

Not Found

'.encode()

#     return res

ROUTE_TABLE = {}

@classmethod

def register(cls, path, handler):

cls.ROUTE_TABLE[path] = handler

@dec.wsgify

def __call__(self, request:Request) -> Response:

try:

return self.ROUTE_TABLE[request.path](request)

except:

# return self.notfound(request)

raise exc.HTTPNotFound('您访问的页面被外星人劫持了')   #所有异常都抛404,即便是内部定义的函数有问题也这样,没必要抛5XX之类的错误,防止别人拿到相关信息反推服务器版本之类的,b端不能看到服务器这边的异常

51web开发3_路由功能_exc_路由正则匹配

例:

class MyHTTPNotFound(exc.HTTPNotFound):

code = 404

title = 'nimei'

explanation = 'nimeide'

class Application:

# def notfound(self, request):

#     res = Response()

#     res.body = '

Not Found

'.encode()

#     return res

ROUTE_TABLE = {}

@classmethod

def register(cls, path, handler):

cls.ROUTE_TABLE[path] = handler

@dec.wsgify

def __call__(self, request:Request) -> Response:

try:

      return self.ROUTE_TABLE[request.path](request)

except:

# return self.notfound(request)

# raise exc.MyHTTPNotFound('您访问的页面被外星人劫持了')

raise MyHTTPNotFound()

51web开发3_路由功能_exc_路由正则匹配

ver5,注册函数改造:

到此步,一个框架的雏形基本完成;

Application()是wsgi app,这个应用程序已变成了一个路由程序,处理逻辑已移到外面,外面的这部分就是留给程序员要完成的;

例:

from webob import Request, Response, dec, exc

from wsgiref.simple_server import make_server

class MyHTTPNotFound(exc.HTTPNotFound):

code = 404

title = 'nimei'

explanation = 'nimeide'

class Application:

ROUTE_TABLE = {}

@classmethod

def register(cls, path):

def wrapper(handler):

cls.ROUTE_TABLE[path] = handler

return handler

return wrapper

@dec.wsgify

def __call__(self, request:Request) -> Response:

try:

return self.ROUTE_TABLE[request.path](request)

except:

# raise exc.MyHTTPNotFound('您访问的页面被外星人劫持了')

raise MyHTTPNotFound()

# Application.register('/', index)

# Application.register('/python', showpython)

@Application.register('/')

def index(request):

res = Response()

res.body = '

welcome

'.encode()

return res

@Application.register('/python')

def showpython(request):

res = Response()

res.body = '

hello python

'.encode()

return res

if __name__ == '__main__':

ip = '127.0.0.1'

port = 9999

app = Application()

# app.register('/', index)

# app.register('/python', showpython)

server = make_server(ip, port, app)

try:

server.serve_forever()

except KeyboardInterrupt:

pass

finally:

server.shutdown()

server.server_close()

例,简洁代码:

from wsgiref.simple_server import make_server

from webob import Request, Response, dec, exc

class Application:

ROUTE_TABLE = {}

@classmethod

def register(cls, path):

def wrapper(handler):

cls.ROUTE_TABLE[path] = handler

return handler

return wrapper

@dec.wsgify

def __call__(self, request:Request) -> Response:

try:

return self.ROUTE_TABLE[request.path](request)

except:

raise exc.HTTPNotFound()

@Application.register('/')

def index(request):

res = Response()

res.body = '

welcome

'.encode()

return res

@Application.register('/python')

def showpython(request):

res = Response()

res.body = '

hello python

'.encode()

return res

if __name__ == '__main__':

ip = '127.0.0.1'

port = 9999

server = make_server(ip, port, Application())

try:

server.serve_forever()

except:

pass

finally:

server.shutdown()

server.server_close()

路由正则匹配:

以上的路由实现,非常死板,用re改造;

注册的时候,存入不再是路径字符串,而是pattern;

__call__()实现模式和传入路径的比较;

注:

httpd编译安装前要装pcre;

nginx自身已打包好相关的正则,所以不依赖第三方库;

regex=re.compile(r'PATTERN')   #编译正则表达式;url只一行单选模式即可

regex.match(STRING)   #必须从头开始匹配,只匹配一次

regex.search(STRING)   #只匹配一次

regex.fullmatch(STRING)   #完全匹配

regex.findall(STRING)   #从头开始找,找到所有匹配

py中分组捕获:

/(?P.*)/(?P.*)   #贪婪

/(?P.*?)/(?P.*?)   #非贪婪

例:

@Application.register('/python$')   #只匹配/python

@Application.register('^/$')   #只匹配根,放最后匹配

例:

from wsgiref.simple_server import make_server

from webob import Request, Response, dec, exc

import re

class Application:

# ROUTE_TABLE = {}

ROUTE_TABLE = []   #[(re.compile(pattern), handler)],二元组列表;此处用列表或有序字典;用dict不合适,key是路径模式,不能保证其顺序,匹配的时候应是有序的

@classmethod

def register(cls, pattern):

def wrapper(handler):

cls.ROUTE_TABLE.append((re.compile(pattern), handler))  #注册的时候编译正则表达式

return handler

return wrapper

@dec.wsgify

def __call__(self, request:Request) -> Response:

for regex, handler in self.ROUTE_TABLE:

       matcher = regex.search(request.path)  #match()、search()均可

if matcher:

return handler(request)

raise exc.HTTPNotFound()

@Application.register('^/python$')   #有匹配的顺序,根放到最后;showpython=Application.register('^/python$')(showpython)

def showpython(request):

res = Response()

res.body = '

hello python

'.encode()

return res

@Application.register('^/$')

def index(request):

res = Response()

res.body = '

welcome

'.encode()

return res

if __name__ == '__main__':

ip = '127.0.0.1'

port = 9999

server = make_server(ip, port, Application())

try:

server.serve_forever()

except:

pass

finally:

server.shutdown()

server.server_close()

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


本文名称:51web开发3_路由功能_exc_路由正则匹配-创新互联
文章URL:http://hbruida.cn/article/ppihd.html