Jinja2 在模板表达式中使用数值表达式

Jinja2 using numeric expressions in Template Expressions

我需要做一些看似非常简单的事情:

typedef enum {
    {% for e in mylist %}
    {{ e }} = 0x{{ '%04X' % (1 << loop.index0) }},
    {%- endfor %}
    ALL = 0x0FFF
} Sound_Region_t;

但这会引发“jinja2.exceptions.TemplateSyntaxError:意外的‘<’”

目的是得到类似的东西:

typedef enum {
    foo = 0x0001,
    bar = 0x0002,
    fie = 0x0004,
    fom = 0x0008,
    ...,
    ALL = 0x0FFF
} Sound_Region_t;

即:值是一个“移动位”,因此我可以将它们“按位或”在一起。 如果我尝试使用其他变体,包括“{% with bit = 1 << loop.index %}”或类似的变体,则行为相同。

我错过了什么?

Jinja2 不允许在模板中使用按位运算符,因此我们需要创建一个小的全局函数来执行此类运算符和 returns 一个数字:

def leftshift(amount):
    return 1 << amount

# Get or create a Jinja2 environment
from jinja2 import Environment
env = Environment(...)

# Add leftshift function to the global context
env.globals['leftshift'] = leftshift

现在我们可以在模板中使用循环索引调用 leftshift 函数:

typedef enum {
    {% for e in mylist %}
    {{ e }} = 0x{{ '{:04X}'.format(leftshift(loop.index0))}},
    {%- endfor %}
    ALL = 0x0FFF
} Sound_Region_t;