On Sun, 07 Jul 2013 23:43:24 +1000, Chris Angelico wrote: > On Sun, Jul 7, 2013 at 11:13 PM, Wayne Werner <wa...@waynewerner.com> > wrote: >> Which you would then use like: >> >> >> conn = create_conn() >> with new_transaction(conn) as tran: >> rows_affected = do_query_stuff(tran) >> if rows_affected == 42: >> tran.commit() > > Yep. There's a problem, though, when you bring in subtransactions. The > logic wants to be like this: [snip hideous code] > I don't like the look of this. It might work, but it's hardly ideal. > This is why I like to be able to nest usages of the same name.
Yes, and the obvious way to nest usages of the same name is to use a instance with a class attribute and instance attribute of the same name: class Example: attr = 23 x = Example() x.attr = 42 print(x.attr) del x.attr print(x.attr) If you need more than two levels, you probably ought to re-design your code to be less confusing, otherwise you may be able to use ChainMap to emulate any number of nested scopes. One interesting trick is you can use a ChainMap as function globals. Here's a sketch for what you can do in Python 3.3: from types import FunctionType from collections import ChainMap class _ChainedDict(ChainMap, dict): # Function dicts must be instances of dict :-( pass def chained_function(func, *dicts): """Return a new function, copied from func, using a ChainMap as dict. """ dicts = dicts + (func.__globals__, builtins.__dict__) d = _ChainedDict(*dicts) name = func.__name__ newfunc = FunctionType( func.__code__, d, name, closure=func.__closure__) newfunc.__dict__.update(func.__dict__) newfunc.__defaults__ = func.__defaults__ return newfunc And in use: py> f = chained_function(lambda x: x+y, {'y': 100}) py> f(1) 101 py> f.__globals__.maps.insert(0, {'y': 200}) py> f(1) 201 py> del f.__globals__.maps[0]['y'] py> f(1) 101 -- Steven -- http://mail.python.org/mailman/listinfo/python-list