Skip navigation
All People > curtvprice > Curtis Price's Blog > 2015 > May
2015

It really is a bit annoying that Calculate Field tool's default (VBScript) parser does not work in x64. Here's a function that saves you typing when you want to default to the PYTHON_9.3 parser. Some Python scripts run this tool many times, so this little shortcut could make your script that much more readable.

 

import arcpy
def CalcField(tbl, field, expr, parser="PYTHON_9.3", codeblock=""):
    """Calculate Field with default Python parser"""
     CalculateField_management(tbl, field, expr, parser, codeblock)

 

How to use the helper function:

 

# Original syntax
arcpy.CalculateField_management("test.dbf", "ZFIELD", "!YFIELD! * 100", "PYTHON_9.3")
# Using the helper function
CalcField("test.dbf", "ZFIELD", "!YFIELD! * 100")

 

Why PYTHON_9.3 instead of PYTHON?

The PYTHON_9.3 is pretty much the same (performance-wise) as the PYTHON, but the difference comes in when a code block is used.  In the 9.3  [and later] geoprocessor ("PYTHON_9.3"), arcpy.List* functions return Python lists, not enumerators, and arcpy tools and methods return arcpy Result objects (not strings). This is especially important if your code block needs to work with geometry objects which are much easier to manipulate as objects instead of string representations.

I have run across the need to save and restore the arcpy environment. For example, a function (or a tool packaged in a function) may alter the environment and it would be nice to have an easy way to set it back at the end.

 

Arcpy provides the functions SaveSettings and LoadSettings, but they require that an XML file be created. I was having problems with these functions and had a epiphany that this could be more easily done by combining the ListEnvironments function and a Python dictionary.

 

Enjoy!

 

def SaveEnv():
    """Save selected arcpy environments as dict"""
    env_dict = {}
    for e in arcpy.ListEnvironments():
        if e not in ["scratchGDB", "scratchFolder", "packageWorkspace"]:
            env_dict[e] = arcpy.env[e]
    return env_dict

def LoadEnv(env_dict, display=False):
    """Load selected arcpy environments from dict"""
    for e in env_dict.keys():
        arcpy.env[e] = env_dict[e]
        if display:
            arcpy.AddMessage("{0:<30}: {1}".format(e, env_dict[e]))
            print("{0:<30}: {1}".format(e, env_dict[e]))

 

Here's how I am using these functions to keep GISProc from messing up environment when called:

 

def GISProc(arg1, arg2):
    envs = SaveEnv()
    try:
        # Tool goes here ...
        arcpy.env.extent = ...
        arcpy.env.cellSize = ...
    except:
        ...
    finally:
        LoadEnv(envs)