2015-08-16 15 views
0

Я в процессе обучения программированию в скрученном и проходящем учебнике Dave Peticolas (http://krondo.com/wp-content/uploads/2009/08/twisted-intro.html). Я пытаюсь решить предлагаемое упражнение в конце части 3 - с несколькими обратными отсчетами, идущими на countdown.py. Вот мой код, и ошибка я получаю:AssertionError: None не является вызываемым

#!/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 

Я предполагаю, что я не делаю что-то неправильно в мобилизации объектную переменную; хотя я не уверен, что я делаю неправильно.

ответ

4

Вы звоните по телефону перед передачей его в. Возвращенный результат вызова 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) 
+0

Спасибо за быстрый ответ. Это решает мою проблему. Я надеялся иметь два отдельных объекта для таймеров; хотя это просто заставляет реактор остановиться, как только первый таймер истечет. Каков наилучший способ сделать это? – cronus

Смежные вопросы