Jinja: Verwirrender Fehler mit Python 3 und Vorlagen, die iteritems() verwenden

Erstellt am 27. Sept. 2012  ·  5Kommentare  ·  Quelle: pallets/jinja

Erwägen:

#!/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))

Wenn Sie mit Python 3 ausführen, erhalten Sie eine verwirrende Ausnahme:

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'"

Dies liegt daran, dass die Vorlage iteritems verwendet, die in Python 3 entfernt wurden. Aus der obigen Ausnahme ist nicht klar, dass das Problem in der Vorlage liegt – es sollte so sein.

Es funktioniert für normale Python 3-Wörterbücher, da die Zeilen 205–210 von Jinja2 v2.61 eine iteritems-Methode hinzufügen:

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

Wie kann man das am besten beheben? Diktierähnliche Objekte besser erkennen, versuchen, einen besseren Fehler auszuspucken usw.?

Hilfreichster Kommentar

Wörterbücher haben in 3.x keine iteritem-Methoden. Sie müssen zu .items() wechseln. Da kann ich nichts machen.

Alle 5 Kommentare

Wörterbücher haben in 3.x keine iteritem-Methoden. Sie müssen zu .items() wechseln. Da kann ich nichts machen.

Es wäre schön, wenn es einen eingebauten Filter für diese und andere Python 2to3 Kuriositäten gäbe.

Wenn Sie keine großen Diktate haben, ist die Verwendung von .items() nicht /das/ schlecht

Hier ist eine Möglichkeit, es zu umgehen:

sechs importieren

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

Dann in deiner Vorlage:

verwenden:
{% für Schlüssel, Wert in six_iteritems(Ihre Variable) %}

Es ist irgendwie hässlich, aber es funktioniert.

die Verwendung von .items() anstelle von .iteritems() hat funktioniert

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen