Python

【Python】任意の関数を時間で定期実行する方法

この記事では、Pythonで関数を定期実行させる方法を解説します。timeモジュールなどを使って定義してもいいですが、Scheduleライブラリを使うと簡単に実装することができます。標準ライブラリではないのでインストールする必要がありますが、とても便利なので使ってみてください!

関数を定期実行するには…

任意の関数を定期実行するにはScheduleライブラリを使います。Scheduleは標準ライブラリではないのでpipでインストールしましょう!

ターミナルやコマンドプロンプト

pip install schedule

インストールしたら次に使い方を見ていきましょう!

関数を定期実行させてみる

Scheduleライブラリを使うことで何秒ごと、何分ごと、何時間ごとに関数を実行させたり、毎日17時に実行させたり、曜日を指定して実行させたりと色々指定することができます。

import schedule
import time

# 定期実行する関数
def job():
    print('job実行')


# 1秒ごと
schedule.every(1).seconds.do(job)
# 1分ごと
schedule.every(1).minutes.do(job)
# 1時間ごと
schedule.every(1).hour.do(job)
# 1日ごと
schedule.every(1).days.do(job)
# 毎日17:48
schedule.every().day.at('17:48').do(job)
# 1週間ごと
schedule.every(1).weeks.do(job)
# 毎週水曜日
schedule.every().wednesday.do(job)
# 5秒 ~ 10秒ごと(ランダム)
schedule.every(5).to(10).seconds.do(job)


# 無限ループで実行
while True:
    schedule.run_pending()
    time.sleep(1)

仕組みとしてはschedule.every().***.do()で実行する関数(ジョブ)を登録し、schedule.run_pending()が呼び出された際に条件を満たしているジョブを実行します。

なので、1秒間隔のジョブが登録されていたとしても、schedule.run_pending()が3秒間隔で呼び出されていたとしたら3秒間隔でジョブが実行されます。

このコードを実行するとjob実行がたくさん出力されますが、どこから出力されたか分からないので引数を受け取ってどのジョブが実行されたのかわかりやすく書き換えてみましょう!

ジョブに引数を渡す

定期実行する関数に引数が定義されている場合は、do()に引数の値を指定します。その際、キーワードで指定することもできます。

import schedule
import time

# 定期実行する関数
def job(x):
    print(f'{x}: job実行')

# 1秒ごと
schedule.every(1).seconds.do(job, 'seconds')
# 1分ごと
schedule.every(1).minutes.do(job, x='minutes')
# 5秒 ~ 10秒ごと(ランダム)
schedule.every(5).to(10).seconds.do(job, '5 to 10 seconds')

# 無限ループで実行
while True:
    schedule.run_pending()
    time.sleep(1)

実行結果

seconds: job実行
seconds: job実行
seconds: job実行
seconds: job実行
seconds: job実行
5 to 10 seconds: job実行
seconds: job実行
seconds: job実行
seconds: job実行
seconds: job実行
seconds: job実行
5 to 10 seconds: job実行
seconds: job実行

デコレータを使う

定期実行したい関数にrepeatデコレータを修飾することでも同じように実装できます。repaet()には実行させる時間を指定します。

from schedule import every, repeat, run_pending
import time

@repeat(every(3).seconds)
def job():
    print('job実行')

while True:
    run_pending()
    time.sleep(1)

ジョブに引数を渡したり、1つの関数に複数のデコレータを修飾することもできます。

from schedule import every, repeat, run_pending
import time

@repeat(every(1).seconds, '1 seconds')
@repeat(every(3).seconds, '3 seconds')
def job(x):
    print(f'{x}: job実行')

while True:
    run_pending()
    time.sleep(1)

実行結果

1 seconds: job実行
1 seconds: job実行
3 seconds: job実行
1 seconds: job実行
1 seconds: job実行
1 seconds: job実行
3 seconds: job実行
最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』