Jinja: Непонятная ошибка с Python 3 и шаблонами, использующими iteritems ()

Созданный на 27 сент. 2012  ·  5Комментарии  ·  Источник: pallets/jinja

Рассмотреть возможность:

#!/usr/bin/env python3

from collections import OrderedDict

import jinja2

t = '''
{% for key, value in d.iteritems() %}
* {{ key }}: {{ value }}
{% endfor %}
'''

jt = jinja2.Template(t)

d = OrderedDict()
d['one'] = 1
d['two'] = 2
d['three'] = 3

print(jt.render(d=d))

При запуске с Python 3 возникает сбивающее с толку исключение:

Traceback (most recent call last):
  File "jinja2-OrderedDict.py", line 20, in <module>
    print(jt.render(d=d))
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 895, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 671, in handle_exception
    raise exc_value.with_traceback(tb)
  File "<template>", line 2, in <module>
jinja2.exceptions.UndefinedError: b"'collections.OrderedDict object' has no attribute 'iteritems'"

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

Это работает для обычных словарей Python 3, потому что строки 205–210 Jinja2 v2.61 добавляют обратно метод iteritems:

    # not available on python 3
    if hasattr(dict, 'iterkeys'):
        iterkeys = _all('iterkeys')
        itervalues = _all('itervalues')
        iteritems = _all('iteritems')
    del _all

Как лучше всего это исправить? Лучше обнаруживать dict-подобные объекты, пытаться выдать лучшую ошибку и т. Д.?

Самый полезный комментарий

В словарях нет методов iteritem в 3.x. Вам нужно будет перейти на .items() . Я ничего не могу с этим поделать.

Все 5 Комментарий

В словарях нет методов iteritem в 3.x. Вам нужно будет перейти на .items() . Я ничего не могу с этим поделать.

Было бы неплохо, если бы для этой и других странностей python 2to3 был встроенный фильтр.

Если у вас нет огромных dicts, использование .items() не / это / плохо

Вот способ обойти это:

импорт шесть

env = jinja2.Environment(loader=jinja2.FileSystemLoader('your_dir'))
env.globals['six_iteritems'] = six.iteritems
template = env.get_template('your_template')

Затем в вашем шаблоне:

использовать:
{% для ключа, значение в six_iteritems (ваша переменная)%}

Это некрасиво, но работает.

используя .items () вместо .iteritems () работал

Была ли эта страница полезной?
0 / 5 - 0 рейтинги