開発支援 AI エージェントの普及で、「毎日 10 時になったら何をしてください」といった定期実行を予約する機会も増えたと思います。
それで運用していると、「今日の午後はキャンセルしたい」のようなこともあると思います。
そのとき、「スクリプトを Ctrl+C で終了 → 実行時刻を修正 → 再実行」とすると再実行を忘れるかもしれないし、累積実行回数などを維持しづらいし、やや不便です。
なので、後から変更するかもしれないことは他のモジュールに分離し、importlib で定期的にリロードします。
注意
- importlib はモジュールのタイムスタンプもファイルサイズも変わらないならリロードしませんが、手編集ならまず変わるはずなので気にしなくてもよいです。
- importlib のリロードは、モジュール内の既存のオブジェクトを削除しないので、もし削除したいなら
delなどが必要です。 - そもそもこの方法は関数自体を挿げ替えるので高い柔軟性がほしいケース向きです。定期実行する時刻や、定期実行を休止する期間を当てはめる形式が定まっているならその設定ファイルを定期的に読み込むほうが行儀がよいです。
例えば、ドーナツを取得する関数を以下のように分離します (実際には定期実行する時刻や、定期実行を休止する期間を取得する関数を分離すると思います)。
funcs.py
def get_doughnut():
return 'ドーナツ'
そして、以下のようにループ内でリロードします。
script.py
import time
import funcs
import importlib
if __name__ == '__main__':
while True:
importlib.reload(funcs) # リロード
print(funcs.get_doughnut())
time.sleep(10) # 実際には 5 分おきなど
そうすると、あるタイミングで funcs.py を「ドーナツ」から「チョコドーナツ」に書き換えれば、スクリプトを再実行しなくても自動的に反映されます。
ドーナツ
ドーナツ
ドーナツ
ドーナツ
チョコドーナツ
チョコドーナツ
もし自動更新したい関数がインスタンスメソッドなら以下のようにします。
funcs.py
def get_doughnut(self):
return 'ドーナツ'
script.py
import time
import funcs
import importlib
from types import MethodType
class Factory:
pass
if __name__ == '__main__':
factory = Factory()
while True:
importlib.reload(funcs) # リロード
factory.get_doughnut = MethodType(funcs.get_doughnut, factory)
print(factory.get_doughnut())
time.sleep(10) # 実際には 5 分おきなど