• tornado模板解析过程总结


    0. RequestHandler中调用loader.load函数,传入模板文件名,生成模板实例
    (1). 检测模板文件名,并返回合法的文件名
    (2). 根据文件名做模板的内容缓存,节省了每次解析模板内容并编译的开销
    (3). 如果未找到编译好的模板,则调用Template类创建新模板


    1. 将内容用_parse函数逐行解析:
    (1). 对于普通的表达式直接加入到_Expression实例中
    (2). 遇到end则直接返回,并继续处理下一行
    (3). 如果都不是,则得到操作符,例如是if,extends等等
    (4). 遇到extends, import, include, set, raw, module则将他们加入到对应的类中
    并将类的实例加入到body.chunks,然后处理下一行
    (5). 根据之前得到的操作符,如果是apply, block, try, if, for, while
    则递归调用_parse处理剩下的内容,直到遇到下一个{%
    (6). 在递归的过程中,将这些块级标记中间的内容加入到对应的类中,例如_Applyblock
    例如_NamedBLock和_ControlBlock
    (7). 最后返回所有处理好的语句


    2. 生成临时函数,这个函数用来执行,并生成最终结果
    (1). 找到当前template中所有语句,是不是有extends别的模板
    (2). 如果有找到,就递归调用loader.loader处理,返回的是生成的模板
    (3). 反转这个包含当前模板,和extends别的模板的列表
    最后被处理的模板会放在最前面,这个模板也就是最终会输出给客户的模板
    (4). 在这个列表中找到引用别的block的内容,就是扩展出来的block
    (5). 以最后被处理的模板作为当前模板,生成临时函数的内容


    3. 循环调用当前的模板中的标记类,分别调用它们的generate函数
    (1). 如果遇到_NamedBlock,将找到的named_block中的内容(引用别的block的)
    写入到最后生成的模板的内容中
    (2). 如果遇到_IncludeBlock,则调用loader.loader生成include模板的内容
    并递归调用find_named_blocks返回被重新定义的block的内容,类似与extends标记的处理方式
    (3). 其他类似与if, while, apply则调用相应的类的generate函数,没有递归的过程
    (4). 将生成的临时函数,写入到StringIO中


    4. 执行临时函数,生成最终函数,执行并返回结果
    (1). 将上一步生成的临时函数,编译成python虚拟机的字节码
    (2). 在namedspace中执行字节码: exec self.compiled in namedspace
    (3). namedspace是包含默认变量,和用户变量的字典
    (4). 生成最终函数,名称为_execute
    (5). 调用最终函数执行结果并返回

  • 相关阅读:
    fmt命令
    wc命令
    grep命令
    head命令
    C/C++语法知识:typedef struct 用法详解
    邻接表无向图的介绍
    邻接矩阵无向图的介绍
    图的基本概念
    careercup-栈与队列 3.6
    careercup-栈与队列 3.5
  • 原文地址:https://www.cnblogs.com/huazi/p/2800082.html
Copyright © 2020-2023  润新知