Greg: > I take it you usually provide a method for explicit cleanup. > How about giving generator-iterators one, then, called > maybe close() or abort(). The effect would be to raise > an appropriate exception at the point of the yield, > triggering any except or finally blocks. Objects already have a perfectly valid cleanup method -- "__del__". If your code is so complicated that it needs a try/yield/finally, it would make much more sense to convert the thing to an iterator object. It probably would make the code a whole lot more understandable, too. (It did happen with mine.) Stated another way: functions which yield stuff are special. If that specialness gets buried in nested try/except/finally/whatever constructs, things tend to get messy. Better make that messiness explicit by packaging the code in an object with well-defined methods. This is actually easy to do because of the existence of iterators, because this code def some_iter(foo): prepare(foo) try: for i in foo: yield something(i) finally: cleanup(foo) painlessly transmutes to this: class some_iter(object): def __init__(foo): prepare(foo) self.foo = foo self.it = foo.__iter__() def next(self): i = self.it.next() return something(i) def __del__(self): cleanup(self.foo) Personally I think the latter version is more readable because the important thing, i.e. how the next element is obtained, is clearly separated from the rest of the code (and one level dedented, compared to the first version). -- Matthias Urlichs
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