実行環境
Windows10
ArcGIS Pro 3.0.3
Python 3.9.11
はじめに
タイトルにある スクリプトツール というのは、ArcGIS Pro アプリケーションから python スクリプトにパラメータを渡して処理を実行する機能のことです。
このスクリプトツールに登録している python スクリプトが、スクリプト内でインポートしている自作モジュールの更新を反映してくれないという現象にずっと悩まされていました。
更新を反映させるにはアプリケーションを再起動させないといけないので煩わしいことこの上なかったのですが、やっと解決策を見つけました。
標準ライブラリ importlib の reload() でモジュールをリロードする。
これだけの話だったのですが、調べてもすぐに答えにたどり着けなかったので、ここに書き留めたいと思います。
モジュールの更新が反映されないケース
以下の tool.py と mod.py が、同じフォルダ内にある場合です。
# スクリプトツールに登録する python スクリプトファイル
import arcpy
import mod
arcpy.AddMessage('tool')
arcpy.AddMessage(mod.get_text())
# インポートするモジュールファイル
def get_text():
return 'mod'
arcpy というのは、ArcGIS Pro の提供するライブラリです。
AddMessage() は、アプリケーション上に文字列を出力します。
ArcGIS Pro から tool.py を登録したスクリプトツールを実行すると、以下の結果になります。
tool と mod が出力されます。
ここで、tool.py と mod.py を以下のように更新し、ファイルを上書き保存します。
import arcpy
import mod
- arcpy.AddMessage('tool')
+ arcpy.AddMessage('tool_changed')
arcpy.AddMessage(mod.get_text())
def get_text():
- return 'mod'
+ return 'mod_changed'
両ファイルとも、出力する文字列のみ変更し、上書き保存します。
この状態で、再度スクリプトツールを実行した結果がこちらです。
tool は tool_changed になっていますが、mod は mod のままです。
このように、読み込んでいるモジュールの変更がスクリプトツールに反映されないという現象が問題となっていました。
ArcGIS Pro を再起動するとモジュールの変更が反映されるようになりますが、面倒です。
解決策
tool.py で、importlib をインポートし reload() で mod モジュールをリロードするようにします。
+ import importlib
import arcpy
import mod
+ importlib.reload(mod)
arcpy.AddMessage('tool_changed')
arcpy.AddMessage(mod.get_text())
結果は以下のとおりで、モジュールの変更が反映されるようになりました。
importlib.reload() について
importlib.reload() の説明のために、ドキュメント を一部抜粋します。
以前にインポートされた module をリロードします。引数はモジュールオブジェクトでなければならず、したがってそれ以前に必ずインポートに成功していなければなりません。この関数は、モジュールのソースファイルを外部エディタで編集していて Python インタープリタから離れることなく新しいバージョンを試したい際に便利です。
今まで知らなかったのですが、Python インタープリタで自作モジュールを扱っている場合でも、普通にあることのようです。
最後に
モジュールの変更が反映されないのはアプリケーションの不具合かと思っていましたが、そうではありませんでした。
そこであらためて、アプリケーション側のリファレンスに書いてなかったものかと探してみたところ、ありました。
ですよね。
ともかくこれで、ArcGIS Pro のカスタムツール作成時の煩わしさから解放されました。