在 mako 表达式中使用按位或

Using bitwise or in mako expression

我们正在将一堆手动代码生成的东西转换为使用 mako 模板,并且我们正在转换的一些代码使用按位或 (|) 运算符来计算一些它的价值。

例如,原来是这样的:

for my_foo in foo_constants():
    output += "#define %s_THING %d\n" % (my_foo.name, my_foo.id | 0x8000)

现在在 mako 中,我们的第一次尝试是:

% for my_foo in foo_constants():
#define ${my_foo.name}_THING ${my_foo.id | 0x10000}
% endfor

但这引发了错误 TypeError: 'int' object is not callable,因为 mako 将该行编译为:

__M_writer(65536(unicode(my_foo.id )))

因为 mako 使用 | 字符表示 "pipe the left to the function on the right"。用额外的一层括号包围表达式,如 ${(my_foo.id | 0x10000)},没有帮助。它产生了

mako.exceptions.SyntaxException: (SyntaxError) invalid syntax (<unknown>, line 1) (u'0x10000),') in file '/tmp/test_template.mako' at line: 2 char: 29

目前,我们只是向模板的上下文中添加一个 bit_or 函数并调用它,但是由于 mako 文档似乎根本没有提到这个问题,我想知道是否我们缺少一个明显的解决方案。


更新:从Mako 1.0.4版本开始,解决方法是多一层括号:

% for my_foo in foo_constants():
#define ${my_foo.name}_THING ${(my_foo.id | 0x10000)}
% endfor

(这在版本 1.0.3 中不起作用,这是发布此问题时的当前版本)

非常接近,您可以尝试只评估按位或在 for 循环中。这对我有用

<%
    class foo(object):
        def __init__(self, name, id):
            self.name = name
            self.id = id
    foo_list = [foo('name1', 123), foo('name2', 23423), foo('name3', 3450)]
%>
% for my_foo in foo_list:
    <% foo_id = my_foo.id | 0x8000 %>
#define ${my_foo.name}_THING ${foo_id}
% endfor

输出为

#define name1_THING 32891

#define name2_THING 56191

#define name3_THING 36218