Python Thread.start()抛出与datetime.datetime相关的奇怪异常

时间:2013-08-27 20:17:39

标签: python multithreading python-2.7

我在python 2.74上使用threading.Timer。这是相关的代码:

__lock = threading.Lock()
def RegeneratePopulationData():
    __lock.acquire()
    print 'I feel regenerated!'
    __lock.release()

def __setRegenerationTimer(firstTime = False):
    global __regenerationTimer
    now = _getNow().date()
    nextRun = datetime(now.year, now.month, now.day + 1, 2, 0)
    __regenerationTimer = threading.Timer((nextRun - _getNow()).total_seconds(), __setRegenerationTimer)
    print 'Regeneration timer set to run in %s' % (nextRun - _getNow())
    print __regenerationTimer.interval
    __regenerationTimer.start()
    if not firstTime:
        RegeneratePopulationData()

def _getNow():
        return datetime.now() + timedelta(hours = TIME_DIF)

这会导致从threading.py抛出TypeError异常。我在网上搜了几个小时,但找不到解决办法。

将threading.py(用于调试目的)的代码更改为第349行,然后执行:

            # than 20 times per second (or the timeout time remaining).
            print _time()
            print timeout
            endtime = _time() + timeout
            delay = 0.0005 # 500 us -> initial delay of 1 ms

这是我得到的例外:

Regeneration timer set to run in 2:52:12.337000
10332.337
1377634067.66
10332.337
1377634067.66
2013-08-27 21:07:47.663000
Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 812, in __bootstrap_inner
    self.run()
  File "C:\Python27\lib\threading.py", line 1082, in run
    self.finished.wait(self.interval)
  File "C:\Python27\lib\threading.py", line 622, in wait
    self.__cond.wait(timeout)
  File "C:\Python27\lib\threading.py", line 350, in wait
    endtime = _time() + timeout
TypeError: unsupported operand type(s) for +: 'float' and 'datetime.datetime'

我无法弄清楚为什么间隔突然变成了日期时间!

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

您的代码未显示timeout的来源。它并非“突然变成”任何东西。无论您的代码是什么,在之前的某个时刻,datetime.datetime都已分配给timeout。要么消除那个条件,要么适当地处理它(也许通过捕获异常)。

更新:您正在修改标准库代码,这是一个非常糟糕的主意。直接或间接地,你传递的是datetime.datetime。使用pdb找出位置。在python控制台中运行您的代码。当您触发异常时import pdb; pdb.pm(),您将进入异常站点的调试器。你可以从那里探索。