import time
from itertools import count
def buzzergen(period):
nexttime = time.time() + period
for i in count():
now = time.time()
tosleep = nexttime - now
if tosleep > 0:
time.sleep(tosleep)
nexttime += period
else:
nexttime = now + period
yield i, nexttime
通常のbuzzergenの起動
from sleepy import buzzergen
import time
buzzer = buzzergen(3) # Planning to wake up each 3 seconds
print time.time()
buzzer.next()
print time.time()
time.sleep(2)
buzzer.next()
print time.time()
time.sleep(5) # Sleeping a bit longer than usually
buzzer.next()
print time.time()
buzzer.next()
print time.time()
import random
for ring in buzzergen(3):
print "now", time.time()
print "ring", ring
time.sleep(random.choice([0, 2, 4, 6]))
そしてそれを実行すると、次のようになります。
now 1400102751.46
ring (0, 1400102754.461676)
now 1400102754.46
ring (1, 1400102757.461676)
now 1400102757.46
ring (2, 1400102760.461676)
now 1400102760.46
ring (3, 1400102763.461676)
now 1400102766.47
ring (4, 1400102769.47115)
now 1400102769.47
ring (5, 1400102772.47115)
now 1400102772.47
ring (6, 1400102775.47115)
now 1400102775.47
ring (7, 1400102778.47115)
ここでは、約1分間に1回、何かが実行される例を紹介します。
time
モジュールの
sleep()`関数]1を使うことができます。この関数は float 引数を取ることができ、サブ秒単位の分解能を得ることができます。眠っているgeneratorを使ったちょっとした遊びです。
質問は時間遅延についてです。固定時間でもよいのですが、場合によっては前回からの遅延時間が必要になることもあります。ここに一つの可能な解決策があります。
直近の時刻からの遅れを計測 (定期的に起床する)
可能な限り定期的に何かを行いたいが、コード中の
last_time
やnext_time
のようなものに煩わされたくないという状況があります。ブザージェネレータ
以下のコード(sleepy.py)は、
ブザーゲン
ジェネレータを定義しています。通常のbuzzergenの起動
そしてそれを実行すると、次のようになります。
ループの中で直接使うこともできます。
そしてそれを実行すると、次のようになります。
このように、このブザーは堅苦しくなく、寝坊しても定期的な睡眠時間に追いつくことができます。