【问题标题】:python/twisted - what is wrong with this code?python/twisted - 这段代码有什么问题?
【发布时间】:2015-01-13 05:26:17
【问题描述】:

我正在学习 Python,目前专注于 Twisted...我正在做一个教程练习,但我似乎无法理解为什么第二版代码中的修改会导致“计数”功能在反应堆启动之前执行。所改变的只是将 's' 参数添加到函数中。

工作:

class Countdown(object):

counter = 5

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

from twisted.internet import reactor

reactor.callWhenRunning(Countdown().count)

print 'Start!'
reactor.run()
print 'Stop!'

破碎:

class Countdown(object):

counter = 5

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

from twisted.internet import reactor

reactor.callWhenRunning(Countdown().count(1))

print 'Start!'
reactor.run()
print 'Stop!'

这是回溯:

Traceback (most recent call last):
  File "C:\Python27\twistedexample\basic-twisted\countdown.py", line 15, in <module>
    reactor.callWhenRunning(Countdown().count(1))
  File "C:\Python27\twistedexample\basic-twisted\countdown.py", line 11, in count
    reactor.callLater(1, self.count(1))
  File "C:\Python27\twistedexample\basic-twisted\countdown.py", line 11, in count
    reactor.callLater(1, self.count(1))
  File "C:\Python27\twistedexample\basic-twisted\countdown.py", line 11, in count
    reactor.callLater(1, self.count(1))
  File "C:\Python27\twistedexample\basic-twisted\countdown.py", line 11, in count
    reactor.callLater(1, self.count(1))
  File "C:\Python27\twistedexample\basic-twisted\countdown.py", line 11, in count
    reactor.callLater(1, self.count(1))
  File "C:\Python27\twistedexample\basic-twisted\countdown.py", line 7, in count
    reactor.stop()
  File "C:\Python27\lib\site-packages\twisted\internet\base.py", line 580, in stop
  "Can't stop reactor that isn't running.")
  ReactorNotRunning: Can't stop reactor that isn't running.

对此的任何意见表示赞赏,我觉得我在这里遗漏了一些重要的东西,不想跳过它。

【问题讨论】:

  • 你应该修复代码示例中的缩进,因为它是一个语法错误:)
  • 哎呀!没注意。我很快就会在这里修复它。顺便说一句,仍然爱 Twisted
  • 谢谢你,你这么说:)。

标签: python twisted


【解决方案1】:

代码的第一个版本传递了对函数 count 的引用(以便以后可以调用它),而损坏的代码版本传递了函数的 result count(1) 的函数调用,它将是 None(因为 count 没有 return 值)。所以你所做的基本上是改变了这个:

reactor.callWhenRunning(Countdown().count)

到这里:

reactor.callWhenRunning(None)

除此之外,您立即调用count(1),而不是注册它以供以后调用!这解释了您看到的错误,因为在您到达reactor.run() 行之前,倒计时正在运行。

这同样适用于调用count(1) 的行reactor.callLater(1, self.count(1)),可能返回None,实际上并没有向callLater 注册任何函数。

【讨论】:

  • 我没有关注...计数仍然被调用,它在遇到错误之前从 5 打印到 1...如果初始 callWhenRunning 使用 None,它怎么能这样做?
  • 尝试不使用reactor.run() 行,我猜它仍然会从5 倒数到1,即使反应堆从未启动!基本上你正在启动count 函数withinreactor.callWhenRunning(Countdown().count(1));它与反应堆无关,该行的内部部分,即Countdown().count(1) 将首先导致count 运行。
  • 为了更清楚,count 是对count 函数的引用;它不运行任何东西。 count() 运行 count 函数。 count(1) 运行 count 函数,参数为 1。
  • 我想我明白了。那么我如何在不启动 count 函数的情况下传递该变量呢?练习的目标是开始多个不同长度的倒计时 - 我试图使用“s”作为倒计时的起点,以替换工作代码的“计数器”变量。
  • 你可以像这样传递它们:reactor.callWhenRunning(Countdown().count, 1)。不过要小心,因为您的 count 函数在调用自身时有点递归,可能不会按照您的意愿行事!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 2018-09-09
相关资源
最近更新 更多