位置: 编程技术 - 正文

深入解析Python的Tornado框架中内置的模板引擎(python 解析算法)

编辑:rootadmin

推荐整理分享深入解析Python的Tornado框架中内置的模板引擎(python 解析算法),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:python求解析解,python解析函数,python解析函数,深入理解python,python求解析解,深入理解python,python解析函数,深入理解python,内容如对您有帮助,希望把文章链接给更多的朋友!

template中的_parse方法是模板文法的解析器,而这个文件中一坨一坨的各种node以及block,就是解析结果的承载者,也就是说在经过parse处理过后,我们输入的tornado的html模板就变成了各种block的集合。这些block和node的祖宗就是这个“抽象”类, _Node,它定义了三个方法定义,其中generate方法是必须由子类提供实现的(所以我叫它“抽象”类)。 理论上来说,当一个类成为祖宗类时,必定意味着这个类包含了一些在子类中通用的行为,那么,从_Node暴露出来的方法来看,即所有的子类理论上都会有如下特征:1. 可作为容器 (each_child, find_named_blocks)2. generate当然了,理想总是丰满的,现实也总有那么点儿不对劲,对于某些子孙,它们的特征看上去不是那么靠谱,比如_Text。 _Text这个类只用到了generate这个方法,用于将文字(Html, JS)经过trim后添加到输入流中,如果调用它的each_child or find_named_blocks,当然你能这么做,但是没有什么意义。 前面反复说到_Parse方法,它返回的结果是一个_ChunkList的实例,而_ChunkList继承与_Node。这是一个体现了_Node容器特点的类,重写了generate方法和each_child方法,而基本上就是依次调用容器内所有元素的相关方法而已。 _Nodes众多子子孙孙中比较奇葩的是_ExtendsBlock这个类,丫什么事情都没做(That is true),看上去像是另外一个“抽象类”,但是居然会被_Parse初始化,用于处理Extends这个token(tornado术语)。我就纳闷了,一旦这货被generate,难道不会抛一个异常出来木? 真正有意思的是另外几个方法,它们有共通的模式,用_ApplyBlock来举例 在_ApplyBlock中,有趣的是generate方法

简单来说,这个函数做了两件事情:定义了一个python文件全局函数叫做applyXXX():,其中的XXX是一个整形的,自增的值,返回值是一个utf8字符串。执行这个applyXXX函数,将此函数的输出再作为self.method这个函数的输入。所以,如果一个类似于这样的模板

会得到一个类似于如下的输出:

tornado的template机制,本质上讲,就是允许开发者已HTML + template marker的方式来编写视图模板,但是在背后,tornado会把这些视图模板通过template的处理,变成可编译的python代码。 拿autumn-sea上面的代码作为例子,比较容易理解: View Template

处理后

实例剖析tornado的模板基本都在template.py这个文件中,短短多行代码就实现了基本可用的模板,让我们慢慢揭开她的面纱。首先我们看看tornado是如何编译模板的,下面是个简单的模板

tornado最后编译代码如下:

是的,你没看错,tornado编译就是将之翻译成一个个代码块,最后通exec传递我们给的参数命名空间执行_tt_execute函数。在我们上面的模板中包含了4种预定义的NODE节点,_ControlBlock,_Expression,_TEXT,每种Node节点都有自己的生成方式。比如说_Expression表达式节点,也就是我们模板中的{{name}},当_parse解析时发现'{'后面还是'{'就认为是表达式节点,

最后生成时会调用节点的generate方法,self.expression就是上面的name,所以当exec的时候就会把name的值append到内部的列表中。像if,for等都是控制节点,他们的定义如下:

控制节点的generate方法有点意义,因为if,for等是下一行是需要缩进的,所以调用了with writer.indent继续缩进控制,可以看下_CodeWriter的indent方法。节点中比较有意思的是_ExtendsBlock,这是实现目标基础的节点,

我们发现并没有定义generate方法,那当生成继承节点时不是会报错吗?让我们看一段事例

当前目录下base.html如下:

我们可以看看解析后的节点,

深入解析Python的Tornado框架中内置的模板引擎(python 解析算法)

由于我们继承了base.html,所以我们的应该以base.html的模板生成,并使用新定义的block代替base.html中的block,这是很正常的思路,tornado也的确是这么干的,只不过处理的并不是在_ExtendsBlock。而实在Template的_generate_python中

_generate_python中调用_get_ancestors获取当前模板的父模板,我们看到如果当前模板的_FILE节点中有_ExtendsBlock就代表有父模板并通过loader.load加载父模板,此时父模板已经是解析过的_FILE节点了。所以,在上面的模板中,ancestors是[当前模板_FILE节点,父模板_FILE节点],ancestors.reverse()后其实ancestors[0]就是父模板,我们看到最后是通过ancestors[0].generate(writer)来生成代码的。那当前模板是如何替换父模板的block内容呢?看上图,block login_name通过解析为_NamedBlock,在_generate_python中通过调用ancestor.find_named_blocks来替换父模板的_NamedBlock的。

其它节点find_named_blocks都没有做什么事,_NamedBlock通过named_blocks[self.name] = self替换为当前模板的_NamedBlock,因为ancestors父模板在前,当前模板在后,所以最后使用的是当前模板的_NamedBlock。生成代码后generate将在给定的命名空间中exec代码

所以在模板中可以使用datetime等,都是通过在这里注入到模板中的,当然还有其它的是通过web.py 中get_template_namespace注入的

我们再来看看tornado的模板是如何对UI模块的支持的。

在使用module时将会生成_Module节点

我们看到其实_Module节点是继承自_Expression节点,所以最后执行的是_tt_modules.Entry(entry)_tt_modules定义在web.py的RequestHandler中

并通过上文的get_template_namespace中注入到模板中。

所以当执行_tt_modules.Entry(entry)时先访问_UIModuleNamespace的__getattr__,后访问__getitem__,最后调用handler._ui_module(key, self.ui_modules[key]),

_tt_modules.Entry(entry)中entry将会传给_ui_module内部的render,也就是args=entryself._active_modules[name] = module(self)此时就是实例化后的UIModule,调用render获取渲染后的内容

当然如果你觉得这么做费事,也可以使用tornado自带的TemplateModule,它继承自UIModule,你可以这么用

在module_entry.html中可以通过set_resources引用需要的静态文件

这里需要注意的是:只能在Template引用的html文件中使用set_resources函数,因为set_resources是TemplateModule.render的内部函数

浅析Python的web.py框架中url的设定方法 网页中的数据在传递的时候有GET和POST两种方式,GET是以网址的形式传参数,在web.py中有着很好的匹配,如果我们配置以下的urlsurls=('/','index','/weixin/(.*)',

Swift 3.0在集合类数据结构上的一些新变化总结 一、Array数组的更改array数组中修改的API示例如下://创建大量相同元素的数组//创建有个String类型元素的数组,并且每个元素都为字符串"Hello"//swift2.2//

Python中内置的日志模块logging用法详解 logging模块简介Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记

标签: python 解析算法

本文链接地址:https://www.jiuchutong.com/biancheng/386971.html 转载请保留说明!

上一篇:使用Python的Tornado框架实现一个Web端图书展示页面(python tonny)

下一篇:浅析Python的web.py框架中url的设定方法(python,web)

  • 出口退税无纸化备案怎么弄
  • 个税申报显示无有效的税费种认定信息已核定
  • 什么是税收超额征收
  • 所得税汇算清缴后发现有误怎么办
  • 水利建设基金一定要交吗
  • 实收资本变化的账务处理
  • 一般纳税人软件销售税率
  • 租赁违法处理
  • 工会经费拨缴是什么意思
  • 贷款未收属于什么科目
  • 开出银行汇票支付手续费
  • 环保公司开具发票怎么开
  • 商业地产会计核算流程
  • 退货冲减收入
  • 新税法下广告费计税依据
  • 公司进项票不够怎么回事
  • 增值税税率和征收率有什么区别
  • 企业扣税账户没钱交税会怎么样?
  • 土地使用权的原值和账面价值
  • 进出口商品应该符合哪个国家的标准
  • 房地产企业的非流动资产周转率在多少以上
  • 初级备考日记
  • 人力成本包括哪三个方面
  • 办理转移登记需要什么资料
  • 企业收到利息收入开发票吗
  • 技术服务合同要盖骑缝章吗
  • 外购无形资产发生的交易费用
  • 个体工商户需要年审吗
  • 解决办法总比困难多
  • 公司转让债务债权协议
  • 公积金怎么做会计科目
  • 企业财产租赁税率
  • 如何向企业账户转钱
  • 车船税不计提怎么做分录
  • vue3微前端
  • 机器学习中的数学原理——对数似然函数
  • html游戏大全
  • 如何在亚马逊平台卖货
  • 城建税退回与不退税区别
  • 公允价值变动损益借贷方向
  • 跨年坏账准备转回
  • 个体工商户没有收入要交税吗
  • 残保金最新
  • python unittest和pytest
  • 酒店行业销售费用占比
  • 网银数字证书年费
  • mongodb查询操作
  • 个人所得税纳税记录怎么查询
  • 职工薪酬都包括什么
  • 已付款未收到货怎么办
  • 募捐建议
  • 注册资本未到位注销公司处理
  • 社保费和公积金计提分录
  • 国税定额发票有什么用
  • 什么是增值税
  • 技术服务发票怎么做成本
  • sql server in()
  • sqlserver允许一列列值重复
  • java开发经常出差合理吗
  • win7桌面计算机
  • ubuntu更换版本
  • win10 怎么恢复
  • mac 照片导入项目没反应
  • linux yum安装apache
  • win7系统无法自动检测此网络的代理设置
  • win10系统字体不清晰
  • win7 设置
  • 原生封装ajax
  • linux文本操作命令
  • OpenGL图元管理
  • Nodejs事件循环机制图解
  • gradle手动安装
  • python模拟操作
  • 居民与非居民的区别国际金融
  • 生猪屠宰企业报价
  • 贵阳税务官网登录
  • 国家税务总局公告2023第12号
  • 购电脑折旧的会计分录
  • 东莞房地产协会副会长
  • 为什么非贸易付不了款呢
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设