Python sched.scheduler超过了最大递归深度 [英] Python sched.scheduler exceeds max recursion depth

查看:89
本文介绍了Python sched.scheduler超过了最大递归深度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始学习Python,而我正在制作的简单应用程序的一部分包括一个计时器,该计时器的hh:mm:ss显示在其自己的线程中运行.

I have recently started learning Python and part of the simple app I am making includes a timer with a hh:mm:ss display running in its own thread.

环顾网络,我发现了两种实现方法:

Looking around the web I found two ways of implementing this:

  1. 使用sched.scheduler
  2. 使用threading.Timer

在两种实现方式中,我的操作方式均相似:

The way I did it looks similar for both implementations:

预定:

def tick(self, display, alarm_time):

    # Schedule this function to run every minute
    s = sched.scheduler(time.time, time.sleep)
    s.enter(1, 1, self.tick, ([display, alarm_time]))

    # Update the time
    self.updateTime(display)

计时器:

def tick(self, display):

    # Schedule this function to run every second
    t = Timer(1, self.tick, (display,alarm_time))
    t.start()

    # Update the time
    self.updateTime(display)

  1. 关于正确的滴答声工作正常,但几分钟后生成以下错误:RuntimeError:超过最大递归深度.我知道您可以手动提高最大递归级别,但是肯定不需要在这里这样做吗?

  1. Works fine with regards to ticking correctly, but generates the following error after a few minutes: RuntimeError: maximum recursion depth exceeded. I know you can increase the max recursion level manually, but surely this should not be necessary here?

没有错误,但有时秒会跳过或不规则地滴答声.

No error, but occasionally the seconds will skip, or tick irregularly.

有人可以指出正确的方向吗?谢谢.

Can someone please point me in the right direction as to how to do this correctly? Thank you.

推荐答案

这里是如何一次性拍摄周期性事件,例如与 sched 一起使用:如果函数必须创建自己的调度程序,并且是唯一在其线程上运行的程序,则:

Here's how to make a one-shot into a periodic event, e.g. with sched: if the function must make its own scheduler and be the only thing running on its thread:

def tick(self, display, alarm_time, scheduler=None):
  # make a new scheduler only once & schedule this function immediately
  if scheduler is None:
    scheduler = sched.scheduler(time.time, time.sleep)
    scheduler.enter(0, 1, self.tick, ([display, alarm_time, scheduler]))
    scheduler.run()

  # reschedule this function to run again in a minute
  scheduler.enter(1, 1, self.tick, (display, alarm_time, scheduler]))

  # do whatever actual work this function requires, e.g.:
  self.updateTime(display)

如果其他事件也必须在同一线程中进行调度,则必须在其他地方创建并拥有调度程序-上面的 if 部分可以重构为其他方法,例如:

If other events must also be scheduled in the same thread then the scheduler must be made and owned "elsewhere" -- the if part above can get refactored into another method, e.g.:

def scheduleperiodic(self, method, *args):
  self.scheduler = sched.scheduler(time.time, time.sleep)
  self.scheduler.enter(0, 1, method, args)
  # whatever else needs to be scheduled at start, if any, can go here
  self.scheduler.run()

def tick(self, display, alarm_time):
  # reschedule this function to run again in a minute
  self.scheduler.enter(60, 1, self.tick, (display, alarm_time))

  # do whatever actual work this function requires, e.g.:
  self.updateTime(display)

当然,再次和 sched 一样,在调度程序运行时,它(和调度的事件回调)将接管"有问题的线程(因此您需要如果您需要同时进行其他操作,请为其单独分配一个线程.

Again, of course and as always with sched, while the scheduler is running, it (and the scheduled event callbacks) will "take over" the thread in question (so you'll need to hive off a separate thread for it if you need other things to be happening at the same time).

如果您需要在许多函数中使用这种习惯用法,可以将其重构为装饰器,但这会掩盖该习惯用法的基本简单性,因此我更喜欢这种简单,公开的用法.顺便说一句,请注意time.time和time.sleep使用秒而不是分钟作为时间单位,因此您需要60(而不是1)来表示从现在开始一分钟";-).

If you need to use this kind of idiom in many functions it could be refactored into a decorator, but that would somewhat mask the underlying simplicity of the idiom, so I prefer this simple, overt use. BTW, note that time.time and time.sleep use seconds, not minutes, as their unit of time, so you need 60, not one, to indicate "a minute from now";-).

这篇关于Python sched.scheduler超过了最大递归深度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆