尝试实现扭曲的延迟列表时的奇怪行为

时间:2014-04-27 09:04:44

标签: python asynchronous twisted

我刚开始扭曲并尝试构建一个简单的POC,但是我不断收到以下错误。

running
[]
running
[]
running
[]
running
[]
running
[]
Traceback (most recent call last):
  File "./poc.py", line 23, in <module>
    dl = defer.DeferredList([tasks])
  File "/usr/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 820, in __init__
    deferred.addCallbacks(self._cbDeferred, self._cbDeferred,
AttributeError: 'list' object has no attribute 'addCallbacks'

我一直在阅读相关的扭曲文档和指南,似乎无法弄清楚我做错了什么。有人知道造成这种异常的原因吗?

#!/usr/bin/env python
from twisted.internet import defer

def task_to_run(data):
  print 'running'
  print data

def finished(res):
  print 'finished', res

tasks = []

for x in range(0,5):
  d = defer.Deferred()      
  d.addCallback(task_to_run)
  tasks.append(d)

dl = defer.DeferredList([tasks])
dl.addCallback(finished) 

2 个答案:

答案 0 :(得分:4)

假设task_to_run确实是异步运行的东西,那么@Elisha就会指出你的问题(你的示例代码列出了列表而不应该)。所以可运行的代码如下:

#!/usr/bin/env python
from twisted.internet import defer

def task_to_run(data):
  print 'running'
  print data

def finished(res):
  print 'finished', res

tasks = []

for x in range(0,5):
  d = defer.Deferred()      
  d.addCallback(task_to_run)
  d.callback("blah - " + str(x)) # Fire them as I make them
  tasks.append(d)

dl = defer.DeferredList(tasks)

dl.addCallback(finished) 

输出:

% ./deferredList.py
running
blah - 0
running
blah - 1
running
blah - 2
running
blah - 3
running
blah - 4
finished [(True, None), (True, None), (True, None), (True, None), (True, None)]

关于DeferredLists的BTW非常好的文档位于:Deferred Reference


但是如果任务实际上没有运行异步,那么你真的可以只创建一个延迟队列:

#!/usr/bin/env python
from twisted.internet import defer

def task_to_run(data):
  print 'running'
  print data
  return data

def finished(res):
  print 'finished', res

d = defer.Deferred()      

for x in range(0,5):
  d.addCallback(task_to_run)

d.addCallback(finished) 

d.callback("blah") # Fire the deferred

运行方式:

% ./deferred.py
running
blah
running
blah
running
blah
running
blah
running
blah
finished blah

答案 1 :(得分:3)

tasks是一个列表。然后将其传递给另一个列表中的DeferredList。 ([tasks]
我想你需要改变这一行:

dl = defer.DeferredList([tasks])

到这一个:

dl = defer.DeferredList(tasks)