ToolValidator クラスのデバッグ

次の図に示すように、ToolValidator クラスをプログラミングするには、ツールを右クリックして、[プロパティ] をクリックし、[確認] タブをクリックして [編集] をクリックします。これにより、IDLE や PythonWin などのインストール済みの Python エディタが開きます。コードを追加し変更を保存したら、エディタを終了して [確認] パネルの [適用] または [OK] をクリックします。

ToolValidator コードの入力

[適用] または [OK] をクリックすると、入力した ToolValidator コードに構文エラーがないかどうかがチェックされます。クラスのメソッドのいずれかに構文エラーがある場合は、構文エラーの説明を示すメッセージ ボックスが表示されるので、そのエラーを修正するまでは編集を適用できません。構文エラーのチェックに加えて、ToolValidator クラスが初期化され、initializeParameters メソッドが呼び出されて、ランタイム エラーがないかどうかがチェックされます。存在しないメソッドの呼び出しを示すランタイム エラーの例を次に示します。

fc = self.params[0].Value  # Should be "value"

ツールのダイアログ ボックスが開かれ updateParametersupdateMessages メソッドが呼び出されたときにこれらの 2 つのメソッドのランタイム エラーが検出されています。ランタイム エラーは最初のパラメータのエラーとして表示されます。次の図に示すように、updateParameters メソッドに入力ミス(Valuevalue など)があります。

ランタイム エラーの表示

このツールを実行するには、ToolValidator コードを編集して、エラーを修正する(この例では Valuevalue に変更する)必要があります。

Describe 関数の使用

Describe 関数の使用は、些細なようで大きな問題の 1 つです。

注意注意:

Describe 関数を使用するときは、値の文字列表現を使用してはなりません。

正しくない例(str 関数を使用)

  desc = arcpy.Describe(str(self.params[0].value))

正しい例

  desc = arcpy.Describe(self.params[0].value)

データセットに文字列表現を使用しないでください(使用した場合、そのデータセットにカタログ パスが生成されます)。これはそのデータセットがディスク上に存在していない場合があるからです(データセットがモデルから導出される変数である場合、そのモデルを先に実行しないと、データセットはディスク上に存在することができません)。(パラメータに導出変数が含まれているかどうかは、parameter.isInputValueDerived メソッドによって確認できます。)データセットの文字列表現を使用した場合は、そのデータセットがまだ存在していない可能性により Describe 関数が失敗することがあります。

テスト前に、パラメータに値が設定されているかどうかを確認

一般的な ToolValidator のコーディングのミスは、初期設定されていない値がないかどうかをテストしないことにあります。

正しくない例(値が設定されていないため arcpy.Describe が失敗)

  fc = self.params[0].value
  shapetype = arcpy.Describe(fc).shapeType.lower()

正しい例(最初に値の有無をテスト)

  fc = self.params[0].value
  if fc:
    shapetype = arcpy.Describe(fc).shapeType.lower()

高度なデバッグ

作成した ToolValidator クラスに構文エラーやランタイム エラーがない場合でも、パラメータが適切に有効化/無効化されてない、デフォルト値の計算が正しくない、出力の記述が正しく入力されていないなど、ロジック エラーが存在している場合があります。従来、スクリプト ツール内のロジック エラーの検出には次の 2 つの手法が用いられてきました。

ToolValidator コードはツールとともに格納され、ダイアログまたはコマンド ラインが使用されるときに一度だけ実行されるため、これらの 2 つの手法を使う場合は ToolValidator での特別な処理が必要になります。

デバッグ メッセージの表示

残念ながら ToolValidator では、メッセージを書き込む場所がないことからメッセージを出力できず、Python の print ディレクティブは無効になります。パラメータ オブジェクトのメソッド setErrorMessagesetWarningMessage を使用したデバッグメッセージの表示には問題があります。これらのメソッドは updateMessages メソッドでのみ使用できますが、表示したいデバッグ メッセージは updateParameters で生成されたものである可能性が高く、したがって、ToolValidator のクラスのメソッド間でデバッグ メッセージを受け渡すことは不可能です。

ただし、次の手法を使用することは可能です。

  • 新しい文字列パラメータをツールに追加して、これを最後のパラメータに設定します。
  • updateParameters で、デバッグ メッセージをこの新しいパラメータに書き込みます。
  • ツールのダイアログ ボックスを開き、値を指定します。デバッグ メッセージがその新しい文字列パラメータで表示されます。
  • 問題を見つけ修正したら、この最後のパラメータをパラメータ リストおよび ToolValidator コード内の使用箇所から削除します。

次のコードは、この手法を具体的に示しています。

  def updateParameters(self):
    if self.params[0].value and not self.params[1].altered:
      desc = arcpy.Describe(self.params[0].value)
      fields = desc.fields
      for field in fields:
        fType = field.type.lower()
        if fType == "smallinteger" or \
           fType == "integer":
          self.params[1].value = field.name

          # Update our "debug" parameter to show
          #  the field type
          #
          self.params[2].value = fType
          break

        # No field, update "debug" parameter
        #
        self.params[1].value = ""
        self.params[2].value = "No field found"
    return

Python IDE でのデバッグ

場合によっては、デバッグ メッセージの出力だけでは十分ではなく、Python IDE(IDLE や PythonWin など)を使用してコードをデバッグし、ブレークポイントの設定、コードの順次確認、値の検査、ロジック エラーの修正を行う必要があります。

デバッグを行うには、スタンドアロン スクリプトを作成してエディタ内でそのスクリプトをデバッグします。スクリプトの最上部では、次に示すように、ツールボックスをロードし、パラメータの配列を作成し、必要なパラメータ値を設定します。

import arcpy

# Load the toolbox and get the tool's parameters, using the tool
#  name (not the tool label).
#
arcpy.ImportToolbox("E:/Documents/Tool Validation Examples.tbx")
params = arcpy.GetParameterInfo("HotSpots_stats")

# Set required parameters
#
params[0].value = "D:/st_johns/city.mdb/roads"

arcpy.GetParameterInfo にはラベルではなくツールの名前が含まれていることに注意してください。これによって、ジオプロセシングで独自のパラメータの配列を作成できるようになります。配列には 1 つ以上のパラメータを設定できます。

次に、作成した ToolValidator コードを追加します([プロパティ] ダイアログ ボックスから直接、コードのコピー/貼り付けを行うことができます)。

スクリプトの下部では、次に示すように ToolValidator を呼び出します。

# Create the ToolValidator class and call updateParameters 
#   and/or updateMessages
#
validator = ToolValidator()
validator.updateParameters()

確認のため、スタンドアロン スクリプトの基本構造を次に示します(実際の ToolValidator コードは、例を簡単にするために削除されています)。

# Create the parameter array and values
#
import arcpy

# Add the toolbox and fetch the parameter list
#
arcpy.ImportToolbox("E:/Documents/Tool Validation Examples.tbx")
params = arcpy.GetParameterInfo("HotSpots_stats")
params[0].value = "D:/st_johns/city.mdb/roads"

# ToolValidator class block
#
class ToolValidator:

  def __init__(self):
    import arcpy 
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    # (initializeParameters code here)
    return

  def updateParameters(self):
    # (updateParameters code here)
    return

  def updateMessages(self):
    # (updateMessages code here)
    return

# Call routine(s) to debug
#
validator = ToolValidator()
validator.updateParameters()
validator.updateMessages()

7/10/2012