Python每秒钟都会调用一个函数?

问题描述:

我有一个游戏,我已经写了我的第一个项目,我想有一个系统,我可以玩和暂停游戏。当你点击取消暂停按钮时,我希望它每1秒钟调用一次函数来提前计算日期。 Time.sleep会停止整个程序,所以对我没有用处,而且我无法在启动线程后重新启动线程。这是推进日的功能。Python每秒钟都会调用一个函数?

def time(): 
    global timer 
    timer = threading.Timer(1.0, time) 
    timer.start() 
    thirtyonemonths = [1, 3, 5, 7, 8, 10, 12] 
    thirtymonths = [4, 6, 9, 11] 
    globalvars.day = globalvars.day + 1 
    for self in thirtyonemonths: 
     if self == globalvars.month: 
      print "hi" 
      if globalvars.day == 32: 
       globalvars.day = 1 
       globalvars.month = globalvars.month + 1 
    for self in thirtymonths: 
     if self == globalvars.month: 
      print "hi" 
      if globalvars.day == 31: 
       globalvars.day = 1 
       globalvars.month = globalvars.month + 1 
    if globalvars.month == 2: 
     print "hi" 
     if globalvars.day == 29: 
      globalvars.day = 1 
      globalvars.month = globalvars.month + 1 
    if globalvars.month == 13: 
     globalvars.month = 1 
     globalvars.year = globalvars.year + 1 
    threading.Thread.time(self) 
timer = threading.Timer(1.0, time) 

后来我当按钮被点击检查它是否暂停或直到我按下按钮第三次

if b.collidepoint(pos): 
    if globalvars.ispaused == 1: 
     globalvars.ispaused = 0 
     timer.start() 
     break 
    if globalvars.ispaused == 0: 
     globalvars.ispaused = 1 
     timer.cancel() 
     break 

一切完美弥补了代码。有谁知道一种方式,我可以重新启动线程或可能使用不同的方法来做我想要的?

+0

@Apero:他正在使用线程。这就是'threading.Timer'的意思。 – abarnert 2014-10-28 19:09:00

+0

http://*.com/questions/8600161/executing-periodic-actions-in-python – 2014-10-28 19:11:49

+0

也看看这个:https://docs.python.org/2/library/sched.html – 2014-10-28 19:12:46

没有看到你的代码的其余部分,这是很难确定是哪里的问题,但我的猜测是,有时,当你点击按钮,ispaused1,但timer是过期的计时器,而不是暂停一。在过期的定时器上调用start不起作用。

虽然这可以修复,但有更简单的方法来做到这一点。

首先,它看起来像你在这里使用某种GUI或游戏框架。我不知道你在使用哪一个,但几乎每个人都有一个定时器的功能(在主事件循环中,而不是在单独的线程中,但这不是关键的事情),更多比threading.Thread强大 - 特别是,它可以每秒自动重复,直到取消。这显然会让你的生活更轻松。

如果不是,那么编写自己的重复Timerfind one on PyPI是很容易的。请注意,threading文档以链接the source code开头。这是因为,就像stdlib中的许多模块一样,threading被写成简单易懂,充当示例代码,本身就是有用的。特别是,Timer是简单的,它应该是非常明显的如何扩展它:只需要围绕run方法进行循环。

+0

非常感谢您的回复。当另一个人提供更简单的解决方案时,我正在扩展Timer。 我结束了刚刚停止我的time()函数的内容,除非未暂停的变量等于1.这样我就不需要启动和停止线程。 – Taegis 2014-10-28 20:42:49

+1

尽管为了将来的参考,当你说“扩展计时器”时,你的意思是把线程库中的原始类的源代码编辑并编辑它?我会复制课程并将其粘贴到我的源代码中吗?我从来没有真正编辑过Python的库。我假设我会重命名它并导入线程库以及?除非你的意思完全不同。我是一个菜鸟:p – Taegis 2014-10-28 20:50:40

+1

或者你可以[扩展班级](http://*.com/a/2706023/786020)。所以像'class MyTimer(threading.Timer):def run(self):while(True):threading.Timer.run(self)''。但不太可能。 – Poik 2014-10-28 21:03:32

在你的函数开始你新的全球每一个时间和一个计时器设置:这是没有必要和必须

global timer 
timer = threading.Timer(1.0, time) 
timer.start() 

然后在函数结束时,您有threading.Thread.time(self)除去。然后在函数声明后你有timer = threading.Timer(1.0, time)这可能是一个错误,因为当它第一次被调用时,全局定时器可能还没有被创建。将最后一行代码替换为time()以在第一次立即调用该函数。更改这两行可能会将代码修复得足够好。

而且,你有你的这样的循环:

for self in thirtyonemonths: 

以及与此问题可能是使用关键字self的。如果这个函数是在一个类中定义的,那么这个self的使用可能被解释为对这个对象的引用。通常最好不要使用关键字self作为迭代器。将自己的所有用法替换为其他内容,比如m来改进您的代码。

+0

啊,好的,谢谢。我在最后摆脱了这段代码,并修复了“自我”的使用。 我结束了刚刚停止我的time()函数的内容,除非未暂停的变量等于1.这样我就不需要启动和停止线程。 – Taegis 2014-10-28 20:58:09