AssertionError: None is not callable

AssertionError: None is not callable

我正在学习如何在 Twisted 中编程,并正在学习 Dave Peticolas 的教程 (http://krondo.com/wp-content/uploads/2009/08/twisted-intro.html)。我正在尝试解决第 3 部分末尾建议的练习 - 进行多个独立的倒计时 countdown.py。这是我的代码,以及我遇到的错误:

#!/usr/bin/python

class countdown(object):

    def __init__(self):
        self.timer = 0

    def count(self, timer):
        if self.timer == 0:
            reactor.stop()
        else:
            print self.timer, '...'
            self.timer -= 1
            reactor.callLater(1, self.count)


from twisted.internet import reactor

obj = countdown()
obj.timer = 10
reactor.callWhenRunning(obj.count(obj.timer))

print 'starting...'
reactor.run()
print 'stopped.'

执行时:

$ ./countdown.py
10 ...
Traceback (most recent call last):
  File "./countdown.py", line 21, in <module>
    reactor.callWhenRunning(obj.count(obj.timer))
  File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 666, in callWhenRunning
    _callable, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 645, in addSystemEventTrigger
    assert callable(_f), "%s is not callable" % _f
AssertionError: None is not callable

我假设我在利用对象变量方面做得不对;虽然我不确定我做错了什么。

你在传入之前称你为可调用obj.count()调用返回结果不可调用

你需要传入方法,而不是调用它的结果:

reactor.callWhenRunning(obj.count, (obj.timer,))

你的方法的位置参数(这里只是 obj.timer)应该作为一个单独的元组给出。

仔细观察,您甚至不需要将 obj.timer 作为参数传入。毕竟直接在self上访问就可以了,不用单独传入:

class countdown(object):
    def __init__(self):
        self.timer = 0

    def count(self):
        if self.timer == 0:
            reactor.stop()
        else:
            print self.timer, '...'
            self.timer -= 1
            reactor.callLater(1, self.count)

并相应地调整您的 callWhenRunning() 调用:

reactor.callWhenRunning(obj.count)