请看下面的代码。我试图将lambda表达式存储在上下文变量中,并在我的自定义模板标记中检索它。但是变量lookup返回一个空字符串而不是我期望的lambda。为什么?任何想法?
感谢
康斯坦丁
>>> c = dict(f = lambda x : 'x=%s' % x)
>>> c['f']
<function <lambda> at 0x02D7FFB0>
>>> template.Variable('f').resolve(c)
''
>>>
答案 0 :(得分:2)
将lambda传递给Django 1.2.4中的模板工作正常,在将我的代码升级到Django 1.3之后,我也遇到了同样的问题。我放弃了尝试设置alters_data标志并尝试在15791中应用补丁,该补丁还添加了do_not_call_in_templates标志(显然在开发版本中合并)。我回避问题直到找到合适的解决方案的方法是使用不带参数的工厂函数返回lambda而不是将lambda传递给模板。
def return_a_lambda():
return lambda x : 'x=%s' % x
c = dict(f=return_a_lambda)
>>> c['f']
<function return_l at 0x33bc668>
template.Variable('f').resolve(c)
<function <lambda> at 0x33ccaa0>
Django的模板调用所有上下文变量,只要它们不需要参数,因此执行return_a_lambda并且模板获得lambda作为回报。
“渲染上下文”下的https://docs.djangoproject.com/en/dev/ref/templates/api/
更新: 可重用的hack是一个返回工厂函数的工厂函数:
def encapsulate(func):
def wrapper():
return func
return wrapper
或更短的版本:
def encapsulate(func):
return lambda: func
最终代码如下:
c = dict(f=encapsulate(lambda x : 'x=%s' % x))
更容易理解。在我的情况下(https://github.com/rosarior/mayan)我现在必须执行大约30次aprox才能在Django 1.3中运行代码:'(
答案 1 :(得分:1)
这是我发现的一张票(我刚刚重新打开,因为我发现,我认为是一个“更好”的解决方案):https://code.djangoproject.com/ticket/15791
答案 2 :(得分:0)
奇怪,它对我有用(使用Django 1.3):
In [9]: from django import template
In [10]: c = dict(f = lambda x : 'x=%s' % x)
In [11]: c['f']
Out[11]: <function <lambda> at 0x00F9D670>
In [12]: template.Variable('f').resolve(c)
Out[12]: <function <lambda> at 0x00F9D670>
但出于好奇,为什么要使用dict而不是django.template.context.Context?
In [19]: c = django.template.context.Context()
In [21]: c['f'] = lambda x: 'x=%s' % x
In [22]: template.Variable('f').resolve(c)
Out[22]: <function <lambda> at 0x01946730>
(我将此留作评论,但我还没有足够的代表)。