>>>>> "TP" == Tim Peters <tim.one@comcast.net> writes: | It would be cool, IMO, if people could define their own | block statements in Python. TP> I think all the use cases you had in mind fit this too, and TP> it's not vacuous. Indeed. Here's a strawman pure-Python implementation based on Bernard Herzog's idea. I'm not sure that the semantics of using() are quite right (mine are different than Bernard's), but that can all be fleshed out in the PEP <287 wink>. Random bizarre thoughts: - maybe a using: block could be named and passed around - maybe `break' would be legal in a using: block - maybe else: could follow a using: block instead of the __else__() method In the following example, imagine that using <expr>: suite() is syntactic sugar for: using(<expr>, suite) seems-neat-and-possibly-even-useful-ly y'rs, -Barry -------------------- snip snip --------------------using.py class IUsing: """A poor-man's interface for a using: expression.""" counter = 0 def __enter__(self): """Called when a using: block is entered.""" def __leave__(self): """Called when a using: block is left, regardless of whether an exception has occurred or not. """ def __exception__(self): """Called when an exception has occurred during a using: block.""" def __else__(self): """Called when a using: block is exited normally.""" def __iter__(self): """Creates an iterative using: block.""" return self def next(self): """Raise StopIteration when an iterative using: block is done.""" # By default, we do exactly one pass through the loop. if not self.counter: self.counter += 1 else: raise StopIteration def using(resource, suite): if not isinstance(resource, IUsing): raise TypeError, 'first argument must be an IUsing' if not callable(suite): raise TypeError, 'second argument must be callable' resource.__enter__() try: try: for __x__ in resource: suite() except: resource.__exception__() raise else: resource.__else__() finally: resource.__leave__() class WithLock(IUsing): # Not part of the IUsing interface... def __init__(self): self.lock = 0 def __enter__(self): print 'acquiring lock' self.lock = 1 def __leave__(self): print 'releasing lock' self.lock = 0 _counter = 0 def once(): global _counter print _counter _counter += 1 # At last! using(WithLock(), once) -------------------- snip snip -------------------- % python /tmp/using.py acquiring lock 0 releasing lock
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4