Tôi đang cố gắng viết một mẫu cây rất đơn giản, đi bộ trong jinja2, sử dụng một số đối tượng tùy chỉnh với các phương thức đặc biệt quá tải (getattr, getitem, v.v.) Có vẻ đơn giản, và đi bộ python tương đương của cây hoạt động tốt, nhưng có một cái gì đó về cách mà sự đệ quy của Jinja làm việc mà tôi không hiểu. Mã được hiển thị bên dưới:Thẻ "đệ quy" của Jinja2 thực sự hoạt động như thế nào?
from jinja2 import Template
class Category(object):
def __init__(self, name):
self.name = name
self.items = {}
self.children = True
def __iter__(self):
return iter(self.items)
def add(self, key, item):
self.items[key] = item
return item
def __getitem__(self, item):
return self.items[item]
def __getattr__(self, attr):
try:
return self.items[attr]
except KeyError:
raise AttributeError(attr)
def __str__(self):
return "<Category '%s'>" % self.name
template = '''
<saved_data>
{% for key in category recursive %}
{% set item = category[key] %}
{% if item.children %}
<category name="{{key}}">
{{ loop(item) }}
</category>
{% else %}
<item name="{{ key }}" value="{{ item }}" />
{% endif %}
{% endfor %}
</saved_data>
'''
b = Category('root')
c = b.add("numbers", Category('numbers'))
c.add("one", 1)
c.add("two", 2)
c.add("three", 3)
d = b.add("letters", Category('letters'))
d.add('ay','a')
d.add('bee','b')
d.add('cee','c')
e = d.add("bools", Category('bools'))
e.add('tru', True)
e.add('fals', False)
def walk(c, depth=0):
for key in c:
item = c[key]
print (' '*depth) + str(item)
if hasattr(item, 'children'):
walk(item, depth+3)
print "Python walking the tree:"
walk(b)
print ""
print "Jinja2 Walking the tree:"
t = Template(template)
print t.render(category = b)
Mẫu đang tăng ngoại lệ như thể đệ quy không thực sự xảy ra. Các cuộc gọi bên trong được thực hiện, nhưng bằng cách nào đó tham chiếu đến 'thể loại' vẫn đề cập đến phụ huynh. Điều gì mang lại ở đây? Phải có một cái gì đó rất cơ bản tôi đang thiếu về cách thức các mẫu đệ quy này có nghĩa vụ phải làm việc. (Hoặc một cái gì đó rất cơ bản ngớ ngẩn mà tôi đang làm mà tôi không thể thấy.
Bạn nên đăng trên danh sách gửi thư của pocoo-libs. Armin (tác giả của Jinja) sẽ thấy bài đăng của bạn ở đó. http://groups.google.com/group/pocoo-libs/topics –