0

我正在破解一个小模板引擎。我有一个生成一串动态生成代码的类(自负地命名为模板编译器)。

例如 :

def dynamic_function(arg):
  #statement
  return rendered_template

在渲染时,我针对此代码调用内置函数exec ,并使用自定义全局字典(为了尽可能控制潜在恶意用户插入到模板中的代码)。

但是,我需要缓存已编译的模板以避免每次执行都编译它。我想知道是否最好将字符串存储为纯文本并每次加载它或使用编译来生成 code_object 并存储该对象(例如使用搁置模块)。

也许值得一提的是,最终我想让我的模板引擎线程安全。

感谢阅读!托马斯

编辑:正如 S.Lott 强调的那样,更好本身并没有意义。我的意思是更好更快,消耗更少的内存更简单,更容易调试。当然,更多更美味的免费咖啡会更好。

4

3 回答 3

2

您没有提到将这些模板存储在哪里,但如果您“永久”地保留它们,请记住 Python 不保证跨主要版本的字节码兼容性。因此,要么选择一种保证兼容性的方法(例如存储源代码),要么在编译模板旁边存储足够的信息,以便在编译模板无效时将其丢弃。

marshal 模块也是如此,例如:使用 Python 2.5 编组的值不承诺在 Python 2.6 中可读。

于 2009-08-18T10:42:21.570 回答
1

就个人而言,我会存储文本。您可以使用编辑器或其他工具查看文本,这将使调试和搞砸更容易。如果您想测试缓存文件的内容是否符合您的预期,那么编写单元测试也容易得多。

稍后,如果您发现您的系统不够快,并且如果分析显示解析缓存的模板需要大量时间,您可以尝试切换到存储字节码 - 但仅限于此。只要正确封装存储机制,这种更改应该是相当轻松的。

于 2009-08-18T11:07:18.883 回答
0

Mako 模板库将编译后的模板缓存为 python 模块,并使用内置imp模块来处理字节码缓存和代码加载。这似乎对解释器中的更改相当健壮,快速且易于调试(您可以在缓存中查看生成代码的源代码)。

请参阅 mako.template模块以了解它如何处理此问题。

于 2009-08-18T10:22:21.237 回答