自定义 Python 工具箱中的工具的行为
验证是在按下工具的确定按钮之前要做的全部工作。创建自己的自定义工具时,可通过验证自定义参数与值相互响应交互的方式。通过一个用于控制工具行为的 Python 代码块执行验证。
要了解有关验证的详细信息,请参阅了解脚本工具中的验证。
在 Python 工具箱中,每个工具参数都拥有一个具有可用于工具验证的属性和方法的关联参数对象。在 Python 工具箱中,在工具类的 getParameterInfo 方法中定义参数。这些参数的行为、它们彼此之间如何交互以及它们与输入参数如何交互,是通过工具类中的 updateParameters 方法进行验证的。
访问工具参数
参数对象构成了在 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。 |
属性
属性名称 |
读/写 |
值 |
描述 |
---|---|---|---|
名称 |
只读 |
字符串 |
参数名称。 |
方向 |
只读 |
字符串:“Input”、“Output” |
参数的输入/输出方向。 |
数据类型 |
只读 |
字符串 |
要获取参数数据类型的列表,请参阅在 Python 工具箱中定义参数数据类型。 |
parameterType |
只读 |
字符串:“Required”、“Optional”、“Derived” |
参数类型。 |
parameterDependencies |
读/写 |
Python 列表 |
各依存参数的索引列表。 |
值 |
读/写 |
Value 对象 |
参数的值。 |
defaultEnvironmentName |
只读 |
字符串 |
默认环境设置。 |
已启用 |
读/写 |
布尔型 |
如果参数不可用,则为 False。 |
已更改 |
只读 |
布尔型 |
如果用户对值做出了修改,则为 True。 |
hasBeenValidated |
只读 |
布尔型 |
如果内部验证例程已检查参数,则为 True。 |
类别 |
读/写 |
字符串 |
参数的类别。 |
方案 |
只读 |
Schema 对象 |
输出数据集的方案。 |
过滤器 |
只读 |
Filter 对象 |
要应用于参数中的值的过滤器。 |
符号系统 |
读/写 |
字符串 |
用于绘制输出的图层文件 (.lyr) 的路径。 |
消息 |
只读 |
字符串 |
要向用户显示的消息。请参阅上文的 SetErrorMessage 和 SetWarningMessage。 |
parameterDependencies
通常会设置参数依赖项以供 Schema 对象使用。在两种情况下可能已经在工具的 getParameterInfo 方法中设置了依赖项。
- 对于类型为“派生”的输出数据集参数,依赖项为参数的索引,可由此派生输出。
- 对于特定的输入数据类型,依赖项为含有控件所用信息的参数的索引,如下表所示。
输入数据类型 |
依赖数据类型 |
描述 |
---|---|---|
字段或 SQL 表达式 |
表 |
含有字段的表。 |
INFO 项目或 INFO 表达式 |
INFO 表 |
含有项目的 INFO 表。 |
Coverage 要素类 |
覆盖范围 |
包含要素的 coverage。 |
面积单位或线性单位 |
地理数据集 |
用于确定默认单位的地理数据集。 |
坐标系 |
工作空间 |
用于确定默认坐标系的工作空间。 |
网络分析等级设置 |
网络数据集 |
包含等级信息的网络数据集。 |
地理统计值表 |
地统计图层 |
包含表的分析图层。 |
parameterDependencies 与脚本工具向导的获取自设置等效。
依赖项通常在 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
值
这是由用户输入的或者通过编程方式设置的参数值。可以在 getParameterInfo 方法中设置 value,此时它用作参数的初始默认值。还可在 updateParameters 中设置 value 以响应用户输入,如下所示。
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].value:
if not parameters[6].altered:
extent = arcpy.Describe(parameters[0].value).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)
With the exception of Describe, don't use methods that take a catalog path, such as ListFields, in validation. The dataset may not exist when your tool is validated in ModelBuilder, and the method may fail or give unexpected results.
In the specific case of ListFields, the Describe object's fields property will provide the equivalent information.
Don't set a parameter value in updateMessages() since the value will not be validated by the internal validation routine.
已更改
如果用户更改了参数值(例如通过输入输出路径进行更改),则 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 (Altered is true).
#
if parameters[0].value:
if not parameters[6].altered:
extent = arcpy.Describe(parameters[0].value).extent
if extent.width > extent.height:
parameters[6].value = extent.width / 100
else:
parameters[6].value = extent.height / 100
return