了解 pystache 中的 lambda
Understanding lambdas in pystache
假设我想在 pystache 中编写一个格式为 2 位浮点数的函数。
我想要上下文中的浮点数和函数(我相信这是 Mustache 的正确哲学)。
我该怎么办?
为了把问题说清楚,我将展示一对我写的代码片段。它们不起作用。
片段(一):
import pystache
tpl = "{{#fmt}}{{q}}{{/fmt}}"
ctx = {
'q' : 1234.5678,
'fmt' : lambda x: "%.2f" % float(x)
}
print pystache.render(tpl, ctx)
失败,错误 "could not convert string to float: {{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() takes exactly 1 argument (0 given)"。我无法理解这个错误:上下文不应该作为参数传递吗?
简答:mustache
不支持这个。它期望所有数据值都经过预处理。
2012 年,在 formating of dates, numbers and more · Issue #41 · mustache/spec,人们提出了各种实施方案,包括。来自其他模板引擎,无法得出任何结论。
根据 mustache.js date formatting , ppl have constructed several extensions and/or workarounds (To me, the most promising one looks to be the {{value | format}}
syntax extension),或建议转移到其他标记引擎。
附加信息:
规格 http://mustache.github.io/mustache.5.html (linked from http://mustache.github.io front page no less) is obsolete, dated 2009. The latest spec that pystache
follows resides at https://github.com/mustache/spec , and looks abandoned, too: the latest commit is dated 02.2015 and the latest spec update is from 2011. Nor does it have a successor。
因此,至此,标准已经失效,因此可以免费增加标记。
我仍然建议在重新发明轮子之前考虑上述讨论中链接的其他格式。
根据ivan_pozdeev的评论,我会post自己的回答。我不会接受它,因为我认为这是一个太丑陋的解决方案。
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)
我也遇到了这个问题。在我用 lambda 调用的已定义方法上设置断点后,我发现 Pystache 传递的数据只是模板的 lambda 子部分。帮助不大。
然后,经过大量的挖掘,我发现
2013 年 11 月 5 日,来自 pystache.renderer
模块的 cjerdonek
mentions accessing the current context via the renderer, and ultimately this code comment:
# 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
谢天谢地,这个实验最终成功了:
- 您的 lambda 必须调用已定义的方法。
- 根据我的经验,严格的内联 lambda 不起作用。
- 您定义的方法必须能够访问渲染器的实例 class。
- 在该方法中,您将获取上下文、处理值并打印它。
- 您的渲染器实例必须用于渲染您的模板和上下文,以便它可以访问上下文。
我构建了以下内容以满足您的要求。这是在 Python 3.6.5 中,为了便于阅读,我扩展了名称。
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)
这会将 1234.57
打印到控制台。
假设我想在 pystache 中编写一个格式为 2 位浮点数的函数。
我想要上下文中的浮点数和函数(我相信这是 Mustache 的正确哲学)。
我该怎么办?
为了把问题说清楚,我将展示一对我写的代码片段。它们不起作用。
片段(一):
import pystache
tpl = "{{#fmt}}{{q}}{{/fmt}}"
ctx = {
'q' : 1234.5678,
'fmt' : lambda x: "%.2f" % float(x)
}
print pystache.render(tpl, ctx)
失败,错误 "could not convert string to float: {{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() takes exactly 1 argument (0 given)"。我无法理解这个错误:上下文不应该作为参数传递吗?
简答:mustache
不支持这个。它期望所有数据值都经过预处理。
2012 年,在 formating of dates, numbers and more · Issue #41 · mustache/spec,人们提出了各种实施方案,包括。来自其他模板引擎,无法得出任何结论。
根据 mustache.js date formatting , ppl have constructed several extensions and/or workarounds (To me, the most promising one looks to be the {{value | format}}
syntax extension),或建议转移到其他标记引擎。
附加信息:
规格 http://mustache.github.io/mustache.5.html (linked from http://mustache.github.io front page no less) is obsolete, dated 2009. The latest spec that pystache
follows resides at https://github.com/mustache/spec , and looks abandoned, too: the latest commit is dated 02.2015 and the latest spec update is from 2011. Nor does it have a successor。
因此,至此,标准已经失效,因此可以免费增加标记。
我仍然建议在重新发明轮子之前考虑上述讨论中链接的其他格式。
根据ivan_pozdeev的评论,我会post自己的回答。我不会接受它,因为我认为这是一个太丑陋的解决方案。
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)
我也遇到了这个问题。在我用 lambda 调用的已定义方法上设置断点后,我发现 Pystache 传递的数据只是模板的 lambda 子部分。帮助不大。
然后,经过大量的挖掘,我发现
2013 年 11 月 5 日,来自 pystache.renderer
模块的 cjerdonek
mentions accessing the current context via the renderer, and ultimately this code comment:
# 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
谢天谢地,这个实验最终成功了:
- 您的 lambda 必须调用已定义的方法。
- 根据我的经验,严格的内联 lambda 不起作用。
- 您定义的方法必须能够访问渲染器的实例 class。
- 在该方法中,您将获取上下文、处理值并打印它。
- 您的渲染器实例必须用于渲染您的模板和上下文,以便它可以访问上下文。
我构建了以下内容以满足您的要求。这是在 Python 3.6.5 中,为了便于阅读,我扩展了名称。
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)
这会将 1234.57
打印到控制台。