Мако: NameError при использовании глобальной переменной

Следующий пример из документов Mako на самом деле не Работа:

<%
    x = 12
%>
<%def name="outer()">
    <%
        y = 15
    %>
    <%def name="inner()">
        inner, x is ${x}, y is ${y}
    </%def>

    outer, x is ${x}, y is ${y}
</%def>

Когда я добавляю <%self:outer /> ниже для вызова def (в файле больше ничего нет), страница выдает ошибку, и мой журнал apache говорит

[Sun Dec 02 13:25:08 2012] [error] [client 89.247.172.1]   File "/tmp/mako_template_cache/index.html.mako.py", line 82, in render_outer
[Sun Dec 02 13:25:08 2012] [error] [client 89.247.172.1]     __M_writer(str(x))
[Sun Dec 02 13:25:08 2012] [error] [client 89.247.172.1]   File "/usr/lib/python3/dist-packages/mako/runtime.py", line 195, in __str__
[Sun Dec 02 13:25:08 2012] [error] [client 89.247.172.1]     raise NameError("Undefined")
[Sun Dec 02 13:25:08 2012] [error] [client 89.247.172.1] NameError: Undefined

Что я могу делать неправильно? У меня есть Mako 0.7.0 от Debian, на котором он должен работать.


person Jo So    schedule 02.12.2012    source источник


Ответы (1)


шаблон, указанный в документах, на самом деле ничего не делает, поскольку он даже не вызывает inner() или outer(). Использование, описываемое в документах, представляет собой локальные вызовы функций:

from mako.template import Template

print Template("""
<%
    x = 12
%>
<%def name="outer()">
    <%
        y = 15
    %>
    <%def name="inner()">
        inner, x is ${x}, y is ${y}
    </%def>

    outer, x is ${x}, y is ${y}

    ${inner()}
</%def>

${outer()}

""").render()

выход:

outer, x is 12, y is 15


    inner, x is 12, y is 15

когда вы вызываете outer() через пространство имен self, это вызывается в другой области видимости переменных, поэтому вы не получаете там «x». «x» определен в определении «body», поэтому только вызов external(), как определено в body(), будет иметь «x».

person zzzeek    schedule 23.12.2012
comment
Спасибо. Так есть ли тег, эквивалентный ${outer()}? (<%outer/> не работает, <%body:outer/> тоже). Или вы просто хотели использовать синтаксис вызова функции для доступа к глобальным переменным? - person Jo So; 24.12.2012
comment
да, я проверил, добавил ли я синтаксис, гарантирующий локальный доступ, и сейчас его нет. Дело в том, что <% a = 5 %> в вашем шаблоне не является глобальным, а локальным для body(). Глобальное значение можно получить с помощью блока <%! %>, поэтому, возможно, вы ищете наследуемые атрибуты. - person zzzeek; 25.12.2012
comment
Было бы полезно, если бы было какое-то замечание по этому поводу на docs.makotemplates.org/en/latest. /defs.html после прочтения Все определения, верхнего уровня или нет, имеют доступ к текущему контекстуальному пространству имен точно так же, как и содержащий их шаблон. У меня сложилось впечатление, что x будет видно , слишком. - person Piotr Dobrogost; 16.05.2013
comment
Хорошо, я думаю, идея в том, что присвоения переменных в шаблоне не являются частью контекста. контекст — это **kw, переданный template.render(). - person zzzeek; 16.05.2013