理解pystache中的lambdas

时间:2017-11-03 15:30:59

标签: python lambda mustache pystache

假设我想编写一个在pystache中以2位数字格式化浮点数的函数。

我想要上下文中的浮点数和函数(我相信这是Mustache的正确理念)。

我该怎么办?

为了解决问题,我将展示我编写的一对代码片段。它们不起作用。

摘录(a):

import pystache

tpl = "{{#fmt}}{{q}}{{/fmt}}"

ctx = {
    'q' : 1234.5678,
    'fmt' : lambda x: "%.2f" % float(x)
}

print pystache.render(tpl, ctx)

此操作失败,错误“无法将字符串转换为浮点数:{{q}}”。我可以理解这个错误:{{fmt}}在{{q}}之前进行评估。

摘录(b):

import pystache

tpl = "{{#q}}{{fmt}}{{/q}}"

ctx = {
    'q' : 1234.5678,
    'fmt' : lambda x: "%.2f" % float(x)
}

print pystache.render(tpl, ctx)

失败并出现错误:“lambda()只取1个参数(0给定)”。我无法理解这个错误:不应该将上下文作为参数传递吗?

3 个答案:

答案 0 :(得分:0)

简短回答:mustache不支持此功能。它希望所有数据值都经过预处理。

2012年,在formating of dates, numbers and more · Issue #41 · mustache/spec,ppl建议各种实施,包括。来自其他模板引擎,无法得出任何结论。

根据mustache.js date formatting,ppl已经构建了几个扩展和/或变通方法(对我来说,最有希望的一个看起来是{{value | format}} syntax extension),或建议转移到其他标记引擎。

其他信息:

http://mustache.github.io/mustache.5.html上的规范(从http://mustache.github.io首页链接不超过)已过时,日期为2009年。pystache所遵循的最新规范位于https://github.com/mustache/spec,并且看起来很像也被放弃了:最新的提交日期为2015年2月,the latest spec update是2011年。Nor does it have a successor

所以,到目前为止,标准已经死了,因此标记可以自由地增加。

我仍然建议在重新发明轮子之前考虑与上述讨论相关的其他格式。

答案 1 :(得分:0)

根据ivan_pozdeev的评论,我会发表自己的答案。我会接受它,因为我认为这是一个太难看的解决方案。

import pystache
import copy

tpl = "{{#fmt}}{{q}}{{/fmt}}"

ctx = {
    'q' : 1234.5678,
}

class OtherContext(object):
    def __init__(self, renderer):
        self.renderer = renderer

    def fmt(self):
        return lambda s: "%.2f" % float(copy.deepcopy(self.renderer).render(s, self.renderer.context))


renderer = pystache.Renderer(missing_tags='strict')

ctx2 = OtherContext(renderer)

print renderer.render(tpl, ctx, ctx2)

答案 2 :(得分:0)

我也有这个问题。在我用lambda调用的已定义方法上设置断点后,我发现Pystache传递的数据只是模板的lambda子部分。不是很有帮助。

然后,经过大量的挖掘,我发现了 在2013年11月5日,cjerdonek mentions通过渲染器访问当前上下文,最终pystache.renderer来自# This is an experimental way of giving views access to the current context. # [...] @property def context(self): """ Return the current rendering context [experimental]. """ return self._context 模块:

import pystache

RENDERER = None


def format_float(template):
    '''
    @param template: not actually used in your use case
        (returns '{{value}}' in this case, which you could render if needed)
    '''
    context_stack = RENDERER.context._stack
    # the data has been last in the stack in my experience
    context_data = context_stack[len(context_stack) - 1]
    x = float(context_data['value'])

    print("%.2f" % x)


if __name__ == '__main__':
    RENDERER = pystache.Renderer()

    template = '{{#formatter}}{{value}}{{/formatter}}'
    context = {
        'value' : 1234.5678,
        'formatter' : lambda template: format_float(template)
    }

    RENDERER.render(template, context)

谢天谢地,这个实验最终有效:

  • 您的lambda必须调用已定义的方法。
    • 根据我的经验,严格的内联lambda不起作用。
  • 您定义的方法必须能够访问Renderer类的实例。
    • 在方法中,您将获取上下文,处理值并打印它。
  • 您的渲染器实例必须用于渲染您的模板和上下文,以便它可以访问上下文。

我构建了以下内容以满足您的要求。这是在Python 3.6.5中,为了便于阅读,我扩展了名称。

1234.57

这会将 Participant.create({ email: `${body.login}@yandex.by`, password: '1111', }, function(err, user) { console.log(user);//undefined 打印到控制台。