能否在Mako模板中从其他Mako模板的Python/Module块导入对象?
能否在Mako模板中从其他Mako模板的Python/Module块导入对象?
嘿,这个问题我之前踩过坑,给你掰扯清楚Mako里这两种代码块的区别和导入可能性:
首先得明确Mako里两种代码块的本质:
<%! %>是模块级代码块:当模板第一次被加载时,这部分代码会被编译成Python模块的全局代码,变量/函数属于模板模块的全局成员,生命周期和模板模块绑定,不是每次渲染都重新定义。<% %>是页面级代码块:这部分代码在模板渲染时才执行,变量属于当前渲染上下文的局部变量,只在这次渲染过程中存在,每次渲染都会重新创建。
1. 导入模块级块(<%! %>)里的对象(比如你的l2)
这个完全可以实现!用你提到的<%namespace>或者<%import>就行,只是要注意访问方式。
举个具体例子:
假设你有个源模板source.mako,内容是:
<%! # 模块级变量,编译后属于模板模块的全局变量 l2 = ['d','e','f'] # 也可以定义模块级函数 def get_l2(): return l2 %>
然后在你的目标模板里,这样访问:
# 导入源模板的namespace <%namespace name="src" file="source.mako" %> <% # 方式1:直接访问模块级变量 my_l2 = src.module.l2 print(my_l2) # 输出: ['d','e','f'] # 方式2:调用模块级函数 another_l2 = src.get_l2() %>
原理很简单:<%namespace>会创建对应模板的Namespace对象,通过它的module属性,你能直接拿到模板编译后的Python模块,模块级的变量/函数自然就能访问到了。
2. 导入页面级块(<% %>)里的对象(比如你的l1)
这个没法直接“导入”!因为l1是source.mako渲染时才会定义的局部变量,它的生命周期只在那一次渲染过程中,而且只属于那个模板的渲染上下文,其他模板根本拿不到这个变量的引用。
如果非要在其他模板里用到类似l1的内容,得换个方式主动暴露:
- 把
l1的定义移到<%! %>模块级块里,变成全局变量,这样就能用上面的方法访问; - 或者在
source.mako里把l1赋值到渲染上下文的全局空间(比如self.context['l1'] = l1),但前提是source.mako必须先被渲染过,上下文里才会有这个变量,这种方式耦合性很高,不推荐; - 最好的方式是把
l1的逻辑封装成模块级函数,像这样:
# source.mako里改成 <%! def get_l1(): return ['a','b','c'] %>
然后在目标模板里通过src.get_l1()获取,这就和访问模块级变量的方式一致了。
总结一下:模块级的对象可以轻松通过namespace导入访问,页面级的局部变量没法直接导入,得换个姿势封装成模块级的内容才行。
备注:内容来源于stack exchange,提问作者durum
相关产品推荐
相关产品推荐

