Всегда ли макросы оцениваются до выражений с Jinja2 - PullRequest
0 голосов
/ 18 марта 2019

Каков порядок операций при рендеринге шаблона с операторами типа macro или do?Кажется, что операторы обрабатываются до выражений независимо от их порядка в шаблоне:

В приведенном ниже примере я ожидал, что Heres the list before macro call: {{ things }} будет сначала "визуализирован" до вызова макроса.

import jinja2

t = """Start of template
{% set things = [] %}
{{ things }}

{% macro mymacro(item) %}
{% do things.append(item) %}
Adding {{ item }} to the list
{% endmacro %}

Heres the list before macro call: {{ things }}
{{ mymacro('1') }}
Heres the list after macro call: {{ things }}
"""

e = jinja2.Environment(extensions=['jinja2.ext.do'])
template = e.from_string(t)
print(template.render())

Результирующий вывод:

Start of template

[]



Heres the list before macro call: ['1']


Adding 1 to the list

Heres the list after macro call: ['1']

1 Ответ

0 голосов
/ 17 апреля 2019

Я нашел ответ на этот вопрос в Github: https://github.com/pallets/jinja/issues/148#issuecomment-10267923

Важной частью для меня является то, что шаблон визуализируется путем генерации промежуточного кода Python, а затем оценки этого кода. В конце код, используемый для создания шаблона, выглядит примерно так:

u'\n%s\n%s\n%s\n%s\n' % (
        l_my_list,
        context.call(l_add_list, l_my_list),
        context.call(l_add_list, l_my_list),
        context.call(l_add_list, l_my_list),
    )

Это можно смоделировать с помощью следующего кода:

def a( l ):
    l.append( 4 )
    return l
l = list()
print '%s %s %s' % ( a( l ), a( l ), a( l ) )
# Output: [4, 4, 4] [4, 4, 4] [4, 4, 4]

По сути, каждая функция возвращает ссылку на один и тот же список, а не новую копию списка. Таким образом, результаты не такие, как вы могли ожидать. Это была старая проблема, которая не вызывала особого интереса, поэтому я не думаю, что есть какие-либо планы изменить ее работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...