自定义 Python 工具箱中的工具行为

验证是在按下工具的确定按钮之前要做的全部工作。创建自己的自定义工具时,可通过验证自定义参数与值相互响应交互的方式。通过一个用于控制工具行为的 Python 代码块执行验证。

要了解有关验证的详细信息,请参阅了解脚本工具中的验证

在 Python 工具箱中,每个工具参数都拥有一个具有可用于工具验证的属性和方法的关联 Parameter 对象。在 Python 工具箱中,在工具类的 getParameterInfo 方法中定义参数。这些参数的行为、它们彼此之间如何交互以及它们与输入参数如何交互,是通过工具类中的 updateParameters 方法进行验证的。

访问工具参数

Parameter 对象构成了在 Python 工具箱中定义参数的方式及其交互方式的基础。标准做法是在工具类的 getParameterInfo 方法中创建参数列表,如以下代码所示。

def getParameterInfo(self):
    #Define parameter definitions
    # First parameter
    param0 = arcpy.Parameter(
        displayName="Input Features",
        name="in_features",
        datatype="GPFeatureLayer",
        parameterType="Required",
        direction="Input")
    return [param0]

有关定义 Python 工具箱中的参数的详细信息,请参阅定义 Python 工具箱中的参数

参数对象

方法

方法名称用法描述

setErrorMessage(message:string)

通过提供的消息将参数标记为存在错误(红色的 X)。如果其中任何参数存在错误,则不会执行工具。

setWarningMessage(message:string)

通过提供的消息将参数标记为存在警告(黄色三角形)。与存在错误时不同,工具在有警告消息的情况下也会执行。

setIDMessage(messageType: string, messageID: string, {AddArgument1}, {AddArgument2})

用于设置系统消息。参数与 AddIDMessage 函数的参数相同。

clearMessage()

清除所有消息文本并将状态设置为信息性的(无错误或警告)。

hasError()

如果参数包含错误,则返回 true。

hasWarning()

如果参数包含警告,则返回 true。

isInputValueDerived()

如果在模型内部验证工具并且输入值是模型中其他工具的输出,则返回 true。

参数对象方法

属性

属性名称读/写说明

name

只读

字符串

参数名称。

direction

只读

字符串:“Input”、“Output”

参数的输入/输出方向。

datatype

只读

字符串

要获取参数数据类型的列表,请参阅在 Python 工具箱中定义参数数据类型

parameterType

只读

字符串:“Required”、“Optional”、“Derived”

参数类型。

parameterDependencies

读/写

Python 列表

各依赖参数的索引列表。

value

读/写

Value 对象

参数的值。

defaultEnvironmentName

只读

字符串

默认环境设置。

enabled

读/写

布尔型

如果参数不可用,则为 False。

altered

只读

布尔型

如果用户对值做出了修改,则为 True。

hasBeenValidated

只读

布尔型

如果内部验证例程已检查参数,则为 True。

category

读/写

字符串

参数的类别。

schema

只读

Schema 对象

输出数据集的方案。

filter

只读

Filter 对象

要应用于参数中的值的过滤器。

symbology

读/写

字符串

用于绘制输出的图层文件 (.lyrx) 的路径。

message

只读

字符串

要向用户显示的消息。请参阅上述 setErrorMessagesetWarningMessage

参数对象属性

虽然很多 Parameter 对象属性为读/写属性,但其中大多数属性只能在最初创建或修改对象时进行设置或修改。多个属性(包括 namedisplayNamedatatypedirectionparameterType)可用于建立工具的特征,且在验证方法(例如 updateMessagesupdateParameters)期间无法修改。

parameterDependencies

通常会设置参数依赖项以供 Schema 对象使用。在两种情况下可能已经在工具的 getParameterInfo 方法中设置了依赖项。

  • 对于类型为“派生”的输出数据集参数,依赖项为参数的索引,可由此派生输出。
  • 对于特定的输入数据类型,依赖项为含有控件所用信息的参数的索引,如下表所示。

输入数据类型依赖数据类型说明

字段或 SQL 表达式

Table

含有字段的表。

INFO 项目或 INFO 表达式

INFO 表

含有项目的 INFO 表。

Coverage 要素类

Coverage

包含要素的 coverage。

面积单位或线性单位

地理数据集

用于确定默认单位的地理数据集。

坐标系

工作空间

用于确定默认坐标系的工作空间。

Network Analyst 等级设置

网络数据集

包含等级信息的网络数据集。

地统计值表

地统计图层

包含表的分析图层。

网络出行模式

网络数据源、网络数据集、网络数据集图层

出行模式列表。

获取自数据类型

依赖项通常在 getParameterInfo 方法中进行设置:

def getParameterInfo(self):
    #Define parameter definitions
    # First parameter
    param0 = arcpy.Parameter(
        displayName="Input Features",
        name="in_features",
        datatype="GPFeatureLayer",
        parameterType="Required",
        direction="Input")
    # Second parameter
    param1 = arcpy.Parameter(
        displayName="Sinuosity Field",
        name="sinuosity_field",
        datatype="Field",
        parameterType="Optional",
        direction="Input")
    param1.value = "sinuosity"
    # Third parameter
    param2 = arcpy.Parameter(
        displayName="Output Features",
        name="out_features",
        datatype="GPFeatureLayer",
        parameterType="Derived",
        direction="Output")
    param2.parameterDependencies = [param0.name]
    param2.schema.clone = True
    params = [param0, param1, param2]
    return params

value

这是由用户输入的或者通过编程方式设置的参数值。可以在 getParameterInfo 方法中设置值,此时该值用作参数的初始默认值。还可在 updateParameters 中设置值以响应用户输入,如下所示。

def updateParameters(self, parameters):
    # Set the default distance threshold to 1/100 of the larger of the width
    #  or height of the extent of the input features.  Do not set if there is no 
    #  input dataset yet, or the user has set a specific distance (Altered is true).
    #
    if parameters[0].valueAsText:
        if not parameters[6].altered:
            extent = arcpy.Describe(parameters[0]).extent
        if extent.width > extent.height:
            parameters[6].value = extent.width / 100
        else:
            parameters[6].value = extent.height / 100
    return

参数的 value 属性会返回一个对象,除非未填充参数,这种情况下 value 将返回 None。要防止未填充参数的情况发生,请在应用参数值前使用 if 条件句执行检查。

下面的代码片段用于测试 value 是否等于字符串“Get Spatial Weights From File”。该测试能够顺利进行是因为参数数据类型是字符串。

# If the option to use a weights file is selected, enable the 
#   parameter for specifying the file, otherwise disable it
if parameters[3].value:  # check that parameter has a value
    if parameters[3].value == "Get Spatial Weights From File":
        parameters[8].enabled = True
    else:
        parameters[8].enabled = False

由于 Value 对象不支持字符串操作,每当操作或解析字符串时都使用 Value 对象的值参数。代码示例使用 os.path.dirname 方法从数据集返回目录。

if parameters[0].value:
    workspace = os.path.dirname(parameters[0].value.value)
注:

请不要使用采用目录路径的方法,例如验证方法中的 ListFields,但是 Describe 例外。在 ModelBuilder 中验证工具时数据集可能并不存在,因此方法可能会失败或产生意外结果。

对于 ListFields 这种特殊情况,Describe 对象的 fields 属性将提供等效信息。

注:

请不要在 updateMessages() 中设置参数值,否则内部验证例程将不会验证该值。

altered

如果参数值被更改(例如通过输入输出路径进行更改),则 altered 为 true。参数更改之后,它会保持更改状态直到用户将该值清空(删除),这时它就恢复到未更改状态。通过验证代码以编程方式更改值将会改变 altered 的状态。也就是说,如果为参数设置了值,参数的 altered 状态将会更新。

altered 用于确定是否可以更改某个参数的值。例如,假设工具拥有要素类参数和关键字参数。如果要素类包含点或面,则关键字为 RED、GREEN 和 BLUE,如果包含线,则关键字为 ORANGE、YELLOW、PURPLE 和 WHITE。

假设用户输入了一个点要素类。如果关键字参数处于未更改状态,则将值设置为 RED,因为它是默认值。

如果输入了线要素类,则将默认值设置为 ORANGE(只要关键字参数处于未更改状态)。

不过,如果用户已更改关键字参数(即,将关键字设置为 GREEN),则不应重置关键字(用户已做出选择 (GREEN),但您还不知道他们的意图),他们可能更改要素类,以使 GREEN 有效,或者可能更改关键字(例如,改为 PURPLE)。由于 GREEN 不是一种为线创建的关键字设置,所以内部验证将参数标记为错误。此时,用户有两种选择:更改输入要素类或者更改关键字。

if not parameters[2].altered:
    parameters[2].value = "POINT"

hasBeenValidated

如果在最后一次调用 updateParameters 和内部验证之后用户修改了参数值,则 hasBeenValidated 为 false。调用内部验证后,地理处理会自动为每个参数将 hasBeenValidated 设置为 true。

hasBeenValidated 用于确定自上次调用 updateParameters 后用户是否对值进行了更改。您可以根据此信息决定是否执行您自己的参数检查。

def updateParameters(self, parameters):
    # Set the default distance threshold to 1/100 of the larger of the width
    #  or height of the extent of the input features.  Do not set if there is no 
    #  input dataset yet, or the user has set a specific distance.
    #
    if parameters[0].valueAsText:
        if parameters[6].hasBeenValidated:
            extent = arcpy.Describe(parameters[0]).extent
            if extent.width > extent.height:
                parameters[6].value = extent.width / 100
            else:
                parameters[6].value = extent.height / 100
    return

相关主题