扭曲的逻辑错误

Posted

技术标签:

【中文标题】扭曲的逻辑错误【英文标题】:Twisted logic error 【发布时间】:2016-08-09 12:38:51 【问题描述】:

我的扭曲程序可以运行,但现在我的一个反应堆没有将优先级传递给其他反应堆。我希望 controlListener 反应器进行一次迭代,然后将优先级传递给 printstuffs 反应器。

 #Random class as proof of concept
 class printStuffs(object):  
         print "counting "
         printerCount = 0
         def count(self):
             self.printerCount = self.printerCount + 1
             print ("the counter is at " + str(self.printerCount))

  ##########################################################################
  ## The control listneer class is designed to kill given reactor threads ##
  ## on demand from something once it recieves a signal it is supposed    ##
  ## to do one ieteration then release                                    ##
  ##########################################################################

  class controlListener(object):
          counter = 20
          def count(self):
               if self.counter == 0:
                  print "Killing Process"
                  reactor.stop()
              else:
                  print self.counter, '...'
                  self.counter -= 1
                  reactor.callLater(1, self.count)

 from twisted.internet import reactor

 print "Printing random stuff"
 reactor.callWhenRunning(printStuffs().count)

 print "Intializing kill listner"
 reactor.callWhenRunning(controlListener().count)
 reactor.run()

 print "Process killed"

这是输出

  Printing random stuff
  Intializing kill listner
  the counter is at 1
  20 ...
  19 ...
  18 ...
  17 ...
  16 ...
  15 ...
  14 ...
  13 ...
  12 ...
  11 ...
  10 ...
  9 ...
  8 ...
  7 ...
  6 ...
  5 ...
  4 ...
  3 ...
  2 ...
  1 ...
  Killing Process
  Process killed

我想让它做类似的事情

 the counter is at 1 
 20 ...
 the counter is at 2 
 the counter is at 3
 19 ...

等等。

有什么想法吗?

【问题讨论】:

我从来没有使用过twisted,但会不会是printStuffs.count() 根本不像reactor.callLater() 那样使用controlListener.count() 来重新调度自己? 你知道了,如果你想要信用将你的帖子复制成一个实际的答案,我会奖励它。 您已经收到了答复,但我只想注意,twisted (twistedmatrix.com/documents/current/api/…) 中有一个 LoopingCall,它可以让您不必手动重新安排重复的呼叫。 【参考方案1】:

您只是忘记让printStuffs.count() 使用reactor.callLater() 重新安排自己,就像controlListener.count() 所做的那样。

class printStuffs(object):  
    printerCount = 0
    def count(self):
        self.printerCount = self.printerCount + 1
        print ("the counter is at " + str(self.printerCount))
        reactor.callLater(1, self.count)

此外,将打印语句 (print "counting") 直接放在类定义中而不是在函数中会导致它在 python 解释器读取类定义时正确运行。这是一种误导,因为消息说“正在计数”,但当时(还)没有真正发生任何事情。


这可能是那些看不到它就看不到它的错误之一。 这就是为什么对于一些重要的函数或线程,我会在我的代码中添加跟踪日志语句来告诉我函数何时被调用,或者线程何时开始何时结束。这对于可能因错误而中止的函数和您希望大部分时间运行的线程特别有用。

这就是你可以如何使这个模式适应你的例子:

class printStuffs(object):
    printerCount = 0
    def count(self):
        try:
            ##print "Entering printStuffs.count()."
            self.printerCount = self.printerCount + 1
            print ("The counter is at " + str(self.printerCount))
            # Run again later.
            reactor.callLater(1, self.count)
        except:
            # We won't run again later.
            print "Error in printStuffs.count(), won't run again:", sys.exc_info()[0]
            # Don't swallow the exception.
            raise
        finally:
            ##print "Leaving printStuffs.count()."

当然,这对于您的示例来说是多余的,但您的实际代码可能更复杂。

当您的程序变得更大更复杂时,以这种方式使用日志记录可以帮助您验证程序中的基本流程是否按预期工作。

【讨论】:

以上是关于扭曲的逻辑错误的主要内容,如果未能解决你的问题,请参考以下文章

错误扭曲模块在Python 3.6.3

Pip 安装扭曲错误 1

为啥这个扭曲的服务器会错误地与进程交互?

旁遮普在 python 上安装扭曲运行错误

Flask扭曲运行时找不到模板目录

在 ubuntu 上为 python 3.5 扭曲