位置: 编程技术 - 正文

深入解析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)

  • 红字发票注明的进项税额转出
  • 公司申报个税流程
  • 增值税专用发票使用规定 最新
  • 企业之间交换房屋 契税
  • 业务招待费是否可以抵扣进项税
  • 贸易企业可以委托代理吗
  • 团建费用会计怎么写记账凭证
  • 网店会计的工作内容是什么
  • 企业所得税连续3年亏损预警自查报告
  • 预收账款转收入附单据吗
  • 个人独资企业可以不开公户吗
  • 建筑业交税会计分录
  • 企业所得税减半征收计算公式
  • 电子钥匙续费能退款吗
  • 企业出售固定资产取得的净收益应列入的利润表项目是
  • 劳务和工资合并扣税吗
  • 公司周年庆典费用计入什么科目
  • 年终奖个税公式 2022
  • 交社保公积金需要劳动合同吗
  • 工伤医疗费会计分录
  • 增值税 附加税
  • 给子公司员工发放奖金合法吗
  • macos12支持设备
  • 清华同方bios通用密码(thtfpc)
  • 事业单位利息收入计入什么科目
  • win10系统中怎么共享文件
  • 收到厂家返利怎么做账务处理
  • 企业会计师证是咋回事
  • 消费税和购置税怎么算
  • 如何解决win7系统卡顿
  • win11咋截屏
  • win7系统不可用怎么办
  • 公司员工意外险怎么买
  • 税收返还的账务处理
  • 损益类科目细分
  • 过路费进项税抵扣填在纳税申报的哪行
  • 保险公司应收账款管理现状及存在的问题
  • 一个红苹果多少钱
  • 多洛米蒂徒步线路
  • 爱丽丝小镇在哪
  • 定期定额和核定征收哪个好
  • js中...的用法
  • 150讲轻松搞定python网络爬虫
  • 企业资产的范围
  • 成本会计制造费用核算的内容
  • 专票红冲要不要收回发票联呢?
  • 环保税计税依据怎么算
  • 劳务费如何开票给客户
  • 金税四期是什么意思
  • 贷款计入什么科目
  • 未开票收入本月要计提增值税吗
  • 金银首饰以旧换新会计处理
  • 自产产品用于业务招待
  • 长期股权投资被投资方实现净利润
  • 住宿发票遗失怎么办
  • 对外公司
  • 商品周转率公式
  • 印花税票 购买
  • 普通发票作废如何操作
  • 废品损失明细账应选择三栏式
  • mysql5.0使用教程
  • Mysql 5.7.19 winx64 ZIP Archive 安装及使用过程问题小结
  • sqlserver远程连接设置
  • smartagt.exe - smartagt是什么进程 什么文件
  • linux批量替换文件夹名称
  • win8屏幕键盘快捷键
  • win8.1隐藏文件夹
  • 照片墙安装教程
  • Node.js中的包管理工具是什么
  • python里的迭代器
  • unity服务器端
  • shell命令怎么用
  • unity 120帧
  • 怎么关闭android
  • 安卓动画不流畅
  • 北京市税务局 案件
  • 辛嵨静志
  • 印花税核定依据填写什么
  • 财税方面的问题有什么
  • 深圳为何
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设