#python #jinja2 #undefined #syntactic-sugar #nested-object
#python #jinja2 #не определено #синтаксический-сахар #вложенный объект
Вопрос:
Я ищу удобный и элегантный способ отображения атрибута вложенного объекта, выбирая первый определенный.
Что-то вроде этого :
from jinja2 import Template
o1 = { "a" : { "b" : { "c" : "John Doe" } } }
o2 = { "e" : { "f" : "John Doe" } }
o3 = { }
template = Template("""Hello {{ o.a.b.c or o.e.f or "John Doe" }}!""")
for o in [o1, o2, o3]:
r = template.render(o=o)
print(r)
Каждая печать должна выводить «Привет, Джон Доу!», первый выводит. Но затем он завершается с jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'a'
ошибкой.
Я пытался использовать defined
, но это означало бы множественное if
утверждение. Чего я бы хотел избежать.
Комментарии:
1. как насчет просто
{{ o["a"] }}
или{{ o.get("a","default") }}
2. согласно документации jinja
o.a
иo["a"]
эквивалентны. И точечная нотация намного понятнее. И дело в том, что если я перепишу свой шаблон с помощью brakets, он завершится точно так же.3. я думаю, вам нужно будет использовать
o.get
Ответ №1:
кажется, это работает нормально
>>> template = Template("""Hello {{ o.get('a',{}).get('b',{}).get('c',None) or o.get('e',{}).get('f',None) or "John Doe" }}!""")
>>> template.render(o=o2)
u'Hello John Doe!'
>>> template.render(o=o1)
u'Hello John Doe!'
>>> template.render(o=o3)
u'Hello John Doe!'
в противном случае, как только ключ не существует, возникает ошибка, которая приводит к короткому замыканию остальной логики … похоже на попытку индексирования в словаре с помощью несуществующего ключа
Комментарии:
1. Это, наверное, самое ясное, что я могу получить. Большое вам спасибо!
2. вы могли бы проделать хитрость с collections defaultdict, но это просто затрудняет последующую отладку, честно