当前位置:网站首页>tornado项目之路由装饰器
tornado项目之路由装饰器
2022-07-04 07:05:00 【youhebuke225】
- 当我们进行启动项目的时候,首先需要的就是注册路由,所以我们可以定义一个方法,这个方法叫
get_handlers
,来获取整个项目的路由 - 但是如何表示一个类是一个路由呢?这个时候,我们就用到了装饰器
open_handler
,经过这个装饰器装饰的类,那么他就是一个路由,所以open_handler
至少有两个参数path
路径index
用于路由排序
装饰器
我们在目录tornado项目core\decorators\open_handler
下写一个装饰器,类作为装饰器 点击
class HandlerDecorate:
"""路由装饰器 1. 实质上路由装饰器只是给装饰的类添加了__url_path__的属性 2. 我们初始化的时候就通过__url_path__这个属性来判断当前的类是路由的处理器 3. __url_path_index__用来给路由进行排序 """
def __init__(self, path, index=None) -> None:
self.__url_path__ = path
self.__url_path_index__ = index
def __call__(self, cls):
cls.__url_path__ = self.__url_path__
cls.__url_path_index__ = self.__url_path_index__
return cls
我们在__init__.py
中暴露这个装饰器
from core.decorators.open_handler.index import HandlerDecorate
open_handler = HandlerDecorate
只要经过@open_hander
修饰的类,就会含有__url_paht__
属性,如
@open_handler(path="/api/(.*)", index=1)
class openApiHandlerService(RequestHandler):
def get(self, *args, **kwargs):
self.write("hello world")
self.finish()
那么,openApiHandlerService就会含有__url_paht__
属性为/api/(.*)
路由的收集
定义get_handlers
方法,来获取被装饰器修饰的类
遍历项目文件
我们需要定义一个遍历项目文件的函数,当前函数用于查找项目中被
open_handler
修饰的类
我们在core\utils\module_utils.py
下,新建一个函数,用于遍历得到某文件下的所有的module
import importlib
import pkgutil
import os
def get_all_modules(path, file_name):
""" 获取路径下的所有file_name的module """
# 获取目录的配置(目录必须是一个包,才会有__path__属性)
_app = importlib.import_module(path)
def get_all_moudules_name(package_path, prefix=""):
# 用于深度遍历文件夹
for loader, name, is_package in pkgutil.iter_modules([package_path]):
if is_package:
# 如果还是一个包,那么再次遍历,且遍历的时候加上前缀
for _name in get_all_moudules_name(os.path.join(package_path, name), prefix=f"{
name}."):
yield prefix + _name
else:
yield prefix + name
return [
importlib.import_module(f"{
path}.{
module_name}")
for module_name in get_all_moudules_name(_app.__path__[0])
if module_name.split(".")[-1][:len(file_name)] == file_name
]
为了规范,我们所有的路由定义的类都凡在开都为handlers
的文件中
获取项目下所有的路由
我们在core\decorators\open_handler
下新建一个OpenHandler
的类,并定义一个get_handlers
的方法用来获取所有的路由
class OpenHandler:
"""路由容器 1. 初始化的时候获取路由的容器类和工具类 2. 返回tornado路由列表 """
def __init__(self, source_libs) -> None:
self.source_libs = source_libs # 传递目录名,用于获取目录下所有使用装饰器的类
self.handler_libs = [] # 存储路由的容器
def get_handlers(self):
self._handler_libs_ = []
_modules = [] # 目录下所有的moudule容器
for _path in self.source_libs:
_modules += get_all_modules(_path, "handler")
for _module in _modules:
self.handler_libs += [
dict(
path=_member.__url_path__,
handler=f"{
_member.__module__}.{
_member.__name__}",
index = _member.__url_path_index__
)
for _name,_member in inspect.getmembers(_module, inspect.isclass)
if hasattr(_member, "__url_path__")
]
# 排序
self.handler_libs.sort(key=lambda x: x['index'])
# 生成tornado的路由对象
_result = []
for _handler_lib in self.handler_libs:
# 遍历生成tornado的路由对象
_path = _handler_lib.get("path")
_result.append(
url(_path, import_object(_handler_lib.get("handler"))))
# 所有的路由列表
return _result
注册路由
一般我们在启动项目的时候需要注册路由
获取handler下的所有路由
为了项目规范我们把所有的路由都注册在了命名为
handler
的文件夹下,在启动环境的时候,我们一般调用Environment
类下的方法,我们在Environment
下,写一个获取handler下的路由的方法
class Environment:
...
def get_all_handlers(self):
open_handler = OpenHandler(["core"])
return open_handler.get_handlers()
他所表示的是获取core
文件夹下的所有的路由,然后我们进行路由的注册
class Application(Application):
def __init__(self):
# 初始化数据库、redis等,项目启动的时候,不要引入模型类
# 注册路由
handlers = environment.get_all_handlers()
# 添加动态路由
super().__init__(handlers, **config.settings)
测试
- 启动项目,我们输入
http://localhost:8888/api/
,就会发现我们可以访问到注册的路由了
边栏推荐
- the input device is not a TTY. If you are using mintty, try prefixing the command with ‘winpty‘
- tars源码分析之10
- How to share the source code anti disclosure scheme
- centos8安装mysql.7 无法开机启动
- 电脑通过Putty远程连接树莓派
- The important role of host reinforcement concept in medical industry
- [Mori city] random talk on GIS data (I)
- Enter the year, month, and determine the number of days
- com. alibaba. nacos. api. exception. NacosException
- 高薪程序员&面试题精讲系列119之Redis如何实现分布式锁?
猜你喜欢
Deep profile data leakage prevention scheme
The crackdown on Huawei prompted made in China to join forces to fight back, and another enterprise announced to invest 100 billion in R & D
Boosting the Performance of Video Compression Artifact Reduction with Reference Frame Proposals and
响应式——媒体查询
Cell reports: Wei Fuwen group of the Institute of zoology, Chinese Academy of Sciences analyzes the function of seasonal changes in the intestinal flora of giant pandas
Node connection MySQL access denied for user 'root' @ 'localhost' (using password: yes
notepad++如何统计单词数量
Cervical vertebra, beriberi
用于压缩视频感知增强的多目标网络自适应时空融合
leetcode825. 适龄的朋友
随机推荐
CMS source code of multi wechat management system developed based on thinkphp6, with one click curd and other functions
js 常用时间处理函数
Highly paid programmers & interview questions: how does redis of series 119 realize distributed locks?
If there are two sources in the same job, it will be reported that one of the databases cannot be found. Is there a boss to answer
"Sword finger offer" 2nd Edition - force button brush question
What is industrial computer encryption and how to do it
【GF(q)+LDPC】基于二值图GF(q)域的规则LDPC编译码设计与matlab仿真
测试用例的设计
Pangu open source: multi support and promotion, the wave of chip industry
Review of enterprise security incidents: how can enterprises do a good job in preventing source code leakage?
Cell reports: Wei Fuwen group of the Institute of zoology, Chinese Academy of Sciences analyzes the function of seasonal changes in the intestinal flora of giant pandas
The number of patent applications in China has again surpassed that of the United States and Japan, ranking first in the world for 11 consecutive years
Mysql 45讲学习笔记(十二)MySQL会“抖”一下
MySQL 45 lecture learning notes (XIII) delete half of the table data, and the table file size remains the same
A new understanding of how to encrypt industrial computers: host reinforcement application
The crackdown on Huawei prompted made in China to join forces to fight back, and another enterprise announced to invest 100 billion in R & D
centos8安装mysql.7 无法开机启动
leetcode825. 适龄的朋友
The most effective futures trend strategy: futures reverse merchandising
MySQL 45 learning notes (XI) how to index string fields