[EMAIL PROTECTED] wrote: > I am using python2.4 and the following code throws a "status variable" > not found in the inner-most function, even when I try to "global" it. > > def collect(fields, reducer): > def rule(record): > status = True > def _(x, y): > cstat = reducer(x, y) > if status and not cstat: > status = False > return y > return reduce(_, [record[field] for field in fields]) > return rule > > What gives?
You rebind status in the inner function. Binding to a name makes it local to that function (unless declared global). A name in an enclosing function is neither local nor global so you cannot rebind it. Ways round this include storing the status in a mutable value, making it an attribute of a class, or rewriting the code to not require setting an outer variable in the first place. The last of these is the easiest in this case: status is never actually used or returned anywhere so you could just remove all references to it with no impact on the code. In fact, so long as reducer has no side effects, you could just do this: def collect(fields, reducer): def rule(record): if fields: return record[fields[-1]] return rule Alternatively, if I assume you actually wanted rule to return the status as well as y, then the outer assignment disappears quite easily: def collect(fields, reducer): def rule(record): def _((x, status), y): cstat = reducer(x, y) return (y, status and cstat) return reduce(_, [record[field] for field in fields], (0, True)) return rule If reducer has no side effects this can be further reduced: def collect(fields, reducer): def rule(record): def _((x, status), y): return (y, status and reducer(x,y)) return reduce(_, [record[field] for field in fields], (0, True)) return rule Given that the final y returned is simply the last record[field] maybe you only wanted the status value? In that case expanding the reduce and _ into inline code is likely to make things clearer: def collect(fields, reducer): def rule(record): prev = 0 for field in fields: if not reducer(prev, record[field]): return False prev = record[field] return True return rule -- http://mail.python.org/mailman/listinfo/python-list