teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

追記

2018/04/17 13:21

投稿

umyu
umyu

スコア5846

answer CHANGED
@@ -5,31 +5,38 @@
5
5
  # -*- coding: utf-8 -*-
6
6
 
7
7
  # ++++ モジュール ++++
8
- import threading
8
+ from threading import Thread
9
9
  from datetime import datetime, timedelta
10
- import sched
10
+ from sched import scheduler
11
11
  import time
12
12
 
13
13
 
14
14
  class GarbageDayReminder(object):
15
15
  def __init__(self):
16
- self.scheduler = sched.scheduler(time.time, time.sleep)
16
+ self.scheduler = scheduler(time.time, time.sleep)
17
17
  # 3秒間隔
18
- self.delay = timedelta(seconds=3)
18
+ self.interval = timedelta(seconds=3)
19
+ # 1日間隔
19
- #self.delay = timedelta(days=1)
20
+ #self.interval = timedelta(days=1)
20
21
 
21
22
  def what_garbage_day(self):
23
+ """
24
+ 指定時間に動作する関数
25
+ """
22
26
  print("今日は何のゴミの日")
23
27
  # 次のスケジュールを登録
24
- self.scheduler.enter(self.delay.total_seconds(), 1, self.what_garbage_day)
28
+ self.scheduler.enter(self.interval.total_seconds(), 1, self.what_garbage_day)
25
29
  #print(self.scheduler.queue)
26
- # 指定時間に動作する関数
30
+
27
31
  def specified_time(self):
32
+ """
33
+ スケジューラーに予定を登録し実行する。
34
+ """
28
35
  now = datetime.now()
29
36
  # call_time の設定
30
- run = now.replace(hour=2, minute=30, second=50, microsecond=0)
37
+ run = now.replace(hour=22, minute=12, second=30, microsecond=0)
31
38
  if now > run:
32
- # クを登録時に時間が経過していたら次の日に
39
+ # スケジュール登録時に時間が経過していたら次の日に
33
40
  run += timedelta(days=1)
34
41
  pass
35
42
  print(f"実行予定時刻:{run}")
@@ -41,7 +48,7 @@
41
48
  # GarbageDayReminderをインスタンス化
42
49
  garbageDayReminder = GarbageDayReminder()
43
50
  # スレッドで指定時間動作関数を動かす
44
- t = threading.Thread(target=garbageDayReminder.specified_time)
51
+ t = Thread(target=garbageDayReminder.specified_time)
45
52
  t.start()
46
53
  print("スレッド動作確認用")
47
54
 
@@ -54,7 +61,8 @@
54
61
  [sched.scheduler.enter](https://docs.python.jp/3/library/sched.html#sched.scheduler.enter)
55
62
 
56
63
  ```
57
- 上記コードはscheduler.enterを使っているため、厳密にはprint文とメソッド呼び出し遅延します。
64
+ 上記コードはscheduler.enterを使っているため、指定時間の呼び出しがミリ秒単位で遅延し累積します。(※)
65
+ ※what_garbage_day関数の処理に掛かる時間とタイマーの精度の問題です。
58
66
  質問文の要件として、そこまで頻繁に呼び出さないタスクだと思われたためこの実装にしましたが。
59
- 問題があるのでしたら、enterabsを使った形に修正してくださいな。
67
+ 問題があるのでしたら、scheduler.enterabsを使った形に修正してくださいな。
60
68
  ```

1

追記

2018/04/17 13:21

投稿

umyu
umyu

スコア5846

answer CHANGED
@@ -10,10 +10,7 @@
10
10
  import sched
11
11
  import time
12
12
 
13
- # ++++ グローバル変数 +++++
14
- call_time = "01:50:50"
15
13
 
16
-
17
14
  class GarbageDayReminder(object):
18
15
  def __init__(self):
19
16
  self.scheduler = sched.scheduler(time.time, time.sleep)
@@ -25,16 +22,12 @@
25
22
  print("今日は何のゴミの日")
26
23
  # 次のスケジュールを登録
27
24
  self.scheduler.enter(self.delay.total_seconds(), 1, self.what_garbage_day)
25
+ #print(self.scheduler.queue)
28
26
  # 指定時間に動作する関数
29
27
  def specified_time(self):
30
- # 変数
31
- format_day = "%Y/%m/%d-"
32
- format_time = "%H:%M:%S"
33
28
  now = datetime.now()
34
- # format_timeだと日付が1990-1-1になるため現在の日付を代入する
35
- now_date = now.strftime(format_day)
36
- # 時間を代入する
29
+ # call_time の設
37
- run = datetime.strptime(now_date + call_time, format_day + format_time)
30
+ run = now.replace(hour=2, minute=30, second=50, microsecond=0)
38
31
  if now > run:
39
32
  # タスクを登録時に時間が経過していたら次の日に
40
33
  run += timedelta(days=1)
@@ -55,4 +48,13 @@
55
48
 
56
49
  if __name__ == '__main__':
57
50
  main()
51
+
52
+ ```
53
+ ◇参考情報
54
+ [sched.scheduler.enter](https://docs.python.jp/3/library/sched.html#sched.scheduler.enter)
55
+
56
+ ```
57
+ 上記コードはscheduler.enterを使っているため、厳密にはprint文とメソッド呼び出し文遅延します。
58
+ 質問文の要件として、そこまで頻繁に呼び出さないタスクだと思われたためこの実装にしましたが。
59
+ 問題があるのでしたら、enterabsを使った形に修正してくださいな。
58
60
  ```