Использование импорта из __future__ в шаблоне Mako

у меня есть

<%!
    from __future__ import division
%>

в самом верху моего файла шаблона. Я получаю сообщение об ошибке:

SyntaxError: from __future__ imports must occur at the beginning of the file 

Как правильно это сделать?


person Hollister    schedule 21.09.2012    source источник


Ответы (2)


Вы не можете использовать операторы from __future__ import в шаблонах Mako. Вообще.

Это связано с тем, что шаблон Mako скомпилирован в файл Python, и для того, чтобы это работало, он устанавливает некоторые начальные структуры в верхней части этого файла Python:

# -*- encoding:ascii -*-
from mako import runtime, filters, cache
UNDEFINED = runtime.UNDEFINED
__M_dict_builtin = dict
__M_locals_builtin = locals
_magic_number = 7
_modified_time = 1348257499.1626351
_template_filename = '/tmp/mako.txt'
_template_uri = '/tmp/mako.txt'
_source_encoding = 'ascii'
_exports = []

Только после этой первоначальной настройки включается какой-либо код из самого шаблона. Ваш from __future__ import division никогда не будет размещен первым.

Вы по-прежнему можете использовать деление с плавающей запятой, приведя любой операнд оператора деления / к типу с плавающей запятой:

>>> 1 / 2
0
>>> float(1) / 2
0.5

Пока вы следуете этому обходному пути, вы можете обойтись без импорта division в будущем.

person Martijn Pieters    schedule 21.09.2012
comment
Да, я видел это при отладке (и что ошибка была в строке 17), но Майк Байер (techspot.zzzeek.org) настолько умен, что я думал, что он приспособился к этому. Кроме того, division — не единственный будущий импорт (на ум приходит with). Я использовал float() до того, как попробовал это. - person Hollister; 22.09.2012
comment
Вам нужно будет отправить запрос функции, чтобы операторы from __future__ with были перемещены в верхнюю часть вывода python для шаблона. Но поскольку такой импорт может изменить само значение шаблона, я не уверен, что это будет хорошей идеей и будет принято Майком Байером или другими сопровождающими Mako. - person Martijn Pieters; 22.09.2012

Импорт из __future__ был бы удобен, но я не могу придумать, как заставить его работать (может быть, кто-то, кто лучше знаком с внутренностями Мако, сможет). Martijn объясняет, почему это невозможно. Я могу предложить пару обходных путей, хотя.

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

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

<%!
    def div(a, b):
        return float(a) / float(b)
%>

Определенно менее элегантно, чем то, что вы имели в виду, но это сработает.

person Philip    schedule 21.09.2012
comment
Подавляющее большинство моей логики находится в представлениях, но в данном случае это некоторая обработка каждой строки данных непосредственно перед ее отображением, поэтому я подумал, что буду держать код ближе к его использованию. Я всегда могу написать вспомогательную функцию и импортировать ее, но это действительно будет аккуратно. - person Hollister; 22.09.2012