How do you get a GIS feature from a Python collection/layer/provider/thingy? Let's look at 4 different popular GIS scripting environments.
ESRI (ArcGIS 9.3):
self.my_collection_count = len(self.my_feature_collection) for i in range(self.my_collection_count): self.my_feature_part = self.my_feature_collection[i] # work with self.my_feature_part ...
Note: don't use instance attributes like that. Use local variables.
OGR (earlier than 1.5):
feature = layer.GetNextFeature() while feature: # work with feature ... feature.Destroy() feature = layer.GetNextFeature()
4 different environments, 4 different ways, and none of them the natural Python way. There's one obviously right way to do it for Python, and that's the way that it's done in ogr.py versions >= 1.5, and how it's done in WorldMill. GeoDjango, too.
where layer is among other things a generator that provides the iterator protocol just like Python strings, lists, and files do. It has a next method that yields a value, or raises a StopIteration exception when there are no more values. The advantages:
- Clarity: it's agonizingly clear. More clear to a non-programmer, in my opinion, than the other alternatives. For each feature in the set: do something. And then forget about the feature and move on to the next.
- Less error-prone: even a non-programmer can't screw up that one line of code any worse than to get a standard, understandable Python NameError, TypeError, or SyntaxError.
- Standardization: core Python modules such as itertools and many other useful add-on packages reward you for using the iterator protocol.