So I was experimenting with somo Odoo code (Qweb templates to be more specific) and I found this function
def foreach_iterator(base_ctx, enum, name):
ctx = base_ctx.copy()
if not enum:
return
if isinstance(enum, int):
enum = xrange(enum)
size = None
if isinstance(enum, Sized):
ctx["%s_size" % name] = size = len(enum)
if isinstance(enum, Mapping):
enum = enum.iteritems()
else:
enum = izip(*tee(enum))
value_key = '%s_value' % name
index_key = '%s_index' % name
first_key = '%s_first' % name
last_key = '%s_last' % name
parity_key = '%s_parity' % name
even_key = '%s_even' % name
odd_key = '%s_odd' % name
for index, (item, value) in enumerate(enum):
ctx[name] = item
ctx[value_key] = value
ctx[index_key] = index
ctx[first_key] = index == 0
if size is not None:
ctx[last_key] = index + 1 == size
if index % 2:
ctx[parity_key] = 'odd'
ctx[even_key] = False
ctx[odd_key] = True
else:
ctx[parity_key] = 'even'
ctx[even_key] = True
ctx[odd_key] = False
yield ctx
# copy changed items back into source context (?)
# FIXME: maybe values could provide a ChainMap-style clone?
for k in base_ctx.keys():
base_ctx[k] = ctx[k]
This function is how t-foreach
is implemented so it is supposed to create an iterator over whatever you pass into it.
But...
>>> list(foreach_iterator({},[1,2,3],"name"))
[{'name': 2,
'name_even': False,
'name_first': False,
'name_index': 1,
'name_last': True,
'name_odd': True,
'name_parity': 'odd',
'name_size': 2,
'name_value': 2},
{'name': 2,
'name_even': False,
'name_first': False,
'name_index': 1,
'name_last': True,
'name_odd': True,
'name_parity': 'odd',
'name_size': 2,
'name_value': 2}]
and then
>>> k = foreach_iterator({},[1,2],"name")
>>> k.next()
{'name': 1,
'name_even': True,
'name_first': True,
'name_index': 0,
'name_last': False,
'name_odd': False,
'name_parity': 'even',
'name_size': 2,
'name_value': 1}
>>> k.next()
{'name': 2,
'name_even': False,
'name_first': False,
'name_index': 1,
'name_last': True,
'name_odd': True,
'name_parity': 'odd',
'name_size': 2,
'name_value': 2}
I've been doing the Python thing for a while now so I know there must be missing some silly thing but for the life of me I can't figure out what is it.
Any takers? Thanks in advance.
The generator function is overwriting the contents of same dict referenced by ctx
again and again.
In the second variant of your test code contents are printed out between overwrites so the changes are visible.
Probably this was meant as some kind of optimization to not create new dictionaries all the time but is obviously dangerous.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.