【python】処理を一時的にストップする方法(sleep関数)

2020年3月31日

他のサーバにアクセスするときに処理負荷を考えて1秒間隔で通信したいなど処理を一旦待ちたいということがあるかと思います。指定した時間だけプログラムを停止するのがsleep関数になります。

sleep関数を使用するときはtimeパッケージが必要です。インポートしておきましょう。

import time

sleep関数を使用する

sleep関数は第1引数に待ちたい秒数を入れるをその時間だけ処理を止めてくれます。
1秒以下の時間を止めたい場合も少数で入力すれば良いです。

使い方

time.sleep( 【待ち時間(単位:秒】)

1秒以下の実行例として0.5秒だけ処理を止めてみましょう。
一瞬ではありますがわずかに2つ目のprint関数の処理が遅れたと思います。

    print("0.5秒間sleepします")
    time.sleep(0.5)
    print("0.5秒間のsleepが完了しました。\n")

実行結果(0.5秒停止)

0.5秒間sleepします
0.5秒間のsleepが完了しました。

1秒以上の例として3秒間処理を止めましょう。
0.5秒と違い明らかに処理が遅れたことが分かります。

    print("3秒間sleepします")
    time.sleep( 3 )
    print("3秒間のsleepが完了しました。\n")

実行結果(3秒停止)

3秒間sleepします
3秒間のsleepが完了しました。

sleep関数の応用 10秒をカウントしてみる

応用として1秒ずつカウントできる10秒タイマを作成します。
1秒のsleepをfor文で10回繰り替すことで10秒をカウントします。

    print( "10秒カウント開始します。" )
    for num in range(10):
        time.sleep( 1 )  #1秒待つ
        print( num + 1 )
    print("10秒経過しました。")

実行結果(10秒カウント)

10秒カウント開始します。
1
2
3
4
5
6
7
8
9
10
10秒経過しました。

sleep関数の弱点 正確な時間の測定には向いていない件(ループの度に時間が遅れる)

先ほど10秒タイマの例を説明しましたが、実は10秒を正確にカウントできていません。
なのでこのブログラムを応用してタイマは作成しないほうが良いです。
10秒程度なら人間に分かる誤差は無いですが100秒、1000秒も待っていると誤差が大きくなります。

誤差が出る理由ですがsleep関数には問題はありません。正確に時間を計測してくれます。(中身を見たことは無いですが、pythonを信じています。)
真の誤差要因は sleep関数以外の処理になります。for文で繰り返す処理であったり、1秒ずつ表示しているprint関数であったり、 sleep関数以外ので時間を消費してしまうのです。
つまり10秒をカウントしても実際には10秒と少しの時間がカウントされます。(時間が遅れます)

sleep関数は非常に簡単ですので正確な時間を必要とされない場合は積極的に使用して問題ありません。
正確な時間を求められる場合は向かないものですので注意が必要です。

以上の誤差要因はpythonだけでなく他の言語のsleep関数でも共通の問題です。
場合によっては致命的な問題になりかねないのでプログラマになるのであればしっかりと押さえておきましょう。


実際にsleepを使用する度に時間が遅れていくところを確認しましょう。
現在時間を取得する関数を使用してどの程度時間が遅れるか確認します。

import datetime
datetime.datetime.now() #現在時間が取得できます。

10秒タイマを改造して、ループの度に現在時間を表示させます。

ソースコード

    import datetime

    start_time = datetime.datetime.now()
    print( "10秒カウント開始します。終了時刻 : " , start_time )

    for num in range(10):
        time.sleep( 1 )  #1秒待つ
        print( num + 1 , " : " , datetime.datetime.now() )

    end_time = datetime.datetime.now()
    print("10秒経過しました。終了時刻 : ", end_time )
    
    diff_time = end_time - start_time
    print( "開始から終了までの時間:", diff_time )

実行結果


10秒カウント開始します。終了時刻 :  2020-03-01 13:01:13.395046
1  :  2020-03-01 13:01:14.395237
2  :  2020-03-01 13:01:15.395688
3  :  2020-03-01 13:01:16.401371
4  :  2020-03-01 13:01:17.403773
5  :  2020-03-01 13:01:18.403959
6  :  2020-03-01 13:01:19.416238
7  :  2020-03-01 13:01:20.416420
8  :  2020-03-01 13:01:21.417610
9  :  2020-03-01 13:01:22.418074
10  :  2020-03-01 13:01:23.427701
10秒経過しました。終了時刻 :  2020-03-01 13:01:23.427701
開始から終了までの時間: 0:00:10.032655

結果を見ると1秒経過するごとに1秒以上時間が経過しています。print文で表示するだけでこれだけ時間が遅れてしまいます。

10秒タイマの開始時と終了時の時間を比較すると10.032655秒経過となります。
単純計算で1000秒待った場合は3秒ほど誤差が出る計算です。
誤差を積み重ねると誤差が大きくなることが分かると思います。
正確な時間を必要とするときはsleep関数をしないように注意してください。

ソースコードはこちらから