The difference in behavior is due to the fact that objects within geoprocessing tools are not the same as objects within ArcPy. The pattern of directly iterating over items in a container, for point in part:
, is a Python use pattern that is implemented in most ArcPy classes but not in ArcObjects classes being used by geoprocessing tools.
Looking to Esri's quick tour of ArcPy:
ArcPy provides access to geoprocessing tools as well as additional
functions, classes, and modules that allow you to create simple or
complex workflows. Broadly speaking, ArcPy is organized in tools,
functions, classes, and modules.
Technically speaking, geoprocessing tools are functions available from
arcpy—that is, they are accessed like any other Python function.
However, to avoid confusion, a distinction is always made between tool
and nontool functions (such as utility functions like
ListFeatureClasses()).
The key is in the second paragraph, i.e., geoprocessing tools are functions available from ArcPy but are not native ArcPy functions. Field Calculator is an example of a geoprocessing tool available through ArcPy as opposed to an ArcPy function that supports Python use patterns. Typically with geoprocessing tools, users either pass basic Python data types (e.g., string) or ArcPy objects that are then converted to geoprocessing objects behind the scenes. Field Calculator is somewhat unique in that users can pass free-form Python code within a Python string for the tool to execute.
In ArcPy, arcobjects
are created from geoprocessing
code and then extended to add support for core Python functionality and patterns. For ArcPy Array
, that includes implementing the Python __iter__
special method that supports the pattern of directly iterating over items in a container. From 3. Data model - Python 3.10.2 documentation:
object.iter(self)
This method is called when an iterator is required for a container.
This method should return a new iterator object that can iterate over
all the objects in the container. For mappings, it should iterate over
the keys of the container.
If you look at the ArrayMixin
class within the mixins
module, you can see the implementation of the iter special method is similar to the Python code that currently works within Field Calculator.
# represenative code since ArcPy modules are copyrighted
def __iter__(self):
for index in xrange(len(self)):
yield conversionObject(self.GetObject(index))
You can verify that a geoprocessing array
does not implement the __iter__
special method while ArcPy Array
does implement it:
>>> import arcpy
>>>
>>> # Create geoprocessing array
>>> gp_arr = arcpy.gp.CreateObject("Array")
>>> type(gp_arr)
<type 'geoprocessing array object'>
>>>
>>> # Create ArcPy Array
>>> arcpy_arr = arcpy.Array()
>>> type(arcpy_arr)
<class 'arcpy.arcobjects.arcobjects.Array'>
>>>
>>> # Check the geoprocessing array for the __iter__ method
>>> gp_arr.__iter__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Array: Get attribute __iter__ does not exist
>>>
>>> # Check the ArcPy Array for the __iter__ method
>>> arcpy_arr.__iter__
<bound method Array.__iter__ of <Array []>>
>>>