脚本工具国际化的最佳做法

要创建一个跨不同语言和区域设置运行良好的脚本工具,遵循最佳做法将非常重要。

避免常见的与区域设置相关的问题

在工具的源代码中,存在两个用于获取参数值的函数:

数据类型为以下类型之一时,arcpy.GetParameter 为首选方法,因此将返回原生 Python 类型。

  • 日期 (GPDate) - 将返回 datetime.datetime 对象。
  • 双精度型 (GPDouble) - 将返回浮点型。
  • 长整型 (GPLong) - 将返回整型。

可以使用 GetParameter 降低解析错误的可能性。 如果数据类型并非上述三种类型之一,则首选 GetParameterAsText 函数。 但是,如果需要任何字符串解析,则应注意正确解析返回值以避免出现错误。

在编写 ArcPy 代码时,请避免将数值表示为字符串。 如果将坐标值表示为字符串,则在不同区域设置中运行代码时可能会遇到错误。 例如,如果在法语区域设置中使用以下第一个示例,则代码可能会失败,因为代码使用句点作为小数分隔符,而大多数法语区域设置则使用逗号。 如果需要将数值表示为字符串,请参阅以下 Python locale 模块部分以获取最佳做法。

将数值表示为字符串。 不建议这样做。

x_coordinate = "-118.24982695975127"
y_coordinate = "34.04771282043386"

将数值表示为数值类型。

x_coordinate = -118.24982695975127
y_coordinate = 34.04771282043386

ArcPy 中的错误处理

如果脚本工具包含针对潜在地理处理错误的错误处理,请使用错误 ID,而非整个错误字符串。 在地理处理工具错误消息中,将针对不同的语言来翻译冒号后面的内容。

检查消息中的整个错误字符串。 仅当消息为英文时,此功能才有效。

try:
    arcpy.analysis.Buffer("cities", "cities_buffer", "500 meters")
except Exception:
    # Catch "ERROR 000732: Input Features: Dataset cities does not exist or is not supported"
    message = "ERROR 000732: Input Features: Dataset cities does not exist or is not supported"
    if message in arcpy.GetMessages(2):
        # Take some action

检查消息中的整个错误字符串。 无论语言或区域设置如何,此方法都有效。 由于未翻译消息的 ERROR 000732 组成部分,因此比较对所有区域设置和语言均有效。

try:
    arcpy.analysis.Buffer("cities", "cities_buffer", "500 meters")
except arcpy.ExecuteError as err:
    # Catch "ERROR 000732: Input Features: Dataset cities does not exist or is not supported"
    message_id = "ERROR 000732"
    if message_id in arcpy.GetMessages(2):
        # Take some action

Python locale 模块

Python locale 模块包含可在脚本工具中实现的本地化功能。

locale.atof 函数可将字符串转换为浮点数,并将本地化数字解析为归一化格式。 当将包含小数分隔符的字符串从非英语区域设置转换为英语区域设置时,此功能将非常有用。

# Import the locale module
import locale

# Use user's default locale settings
locale.setlocale(locale.LC_ALL, '')

# These are coordinates returned assuming the user's locale is French (France).
x_coordinate = "-118,24982695975127"
y_coodinate = "34,04771282043386"

# The output is normalized.
# The following value will be -118.24982695975127 (float).
x_coord_localized = locale.atof(x_coordinate)

# The following value will be 34.04771282043386 (float).
y_coord_localized = locale.atof(y_coordinate)

locale.atof 类似,locale.atoi 函数可将字符串转换为整数,并将本地化数字解析为归一化格式。

# Import the locale module
import locale

# Use user's default locale settings
locale.setlocale(locale.LC_ALL, '')

num_books = "737"

num_books_localized = locale.atoi(num_books)

通过使用 locale.localeconv() 来识别小数点和千位分隔符以避免硬编码分隔符。 由此确保输入将始终具有适合区域设置的千位分隔符和小数分隔符。

# Import the locale module
import locale

# Use user's default locale settings
locale.setlocale(locale.LC_ALL, '')

# Obtain the current locale's separators
thousands_sep = locale.localeconv()['thousands_sep']
decimal_sep = locale.localeconv()['decimal_point']

input_linear_unit = f"2{thousands_sep}259{decimal_sep}50 Miles"

SpatialReference 对象

可以使用三种类型的输入来创建 SpatialReference 对象。

  • 使用坐标系工厂代码(或者权限代码或 WKID)。

    此方法为首选方法,因为它与区域设置无关(这意味着无论区域设置如何,用于引用此空间参考的数值都将保持不变)。

    # EPSG:4301 Tokyo
    sr = arcpy.SpatialReference(4301)

  • 使用坐标系的规范名称。

    此方法类似于使用工厂代码,因为它也与区域设置无关。

    # EPSG:4301 Tokyo
    sr = arcpy.SpatialReference("GCS_Tokyo")
    
    # To obtain a spatial reference's canonical name, you can use the factory code along with the command below
    sr_canonical_name = arcpy.SpatialReference(4301).name

  • 使用坐标系的显示名称。

    如果将在不同的区域设置或语言包上运行代码,则应避免使用此方法。

    # EPSG:4301 Tokyo
    sr = arcpy.SpatialReference("Tokyo")

    以下描述了在日语语言包上运行的代码。 使用英文空间参考显示名称将不起作用并返回错误。 每个语言包都将具有唯一翻译的显示名称;但是,无论语言或区域设置如何,规范名称和工厂代码都将保持不变。 日语语言包中的 Python 窗口以及空间参考示例