Skip to main content
 首页 » 编程设计

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

2025年05月04日16飞鱼

我是 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)  

请您参考如下方法:

假设 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 的非常好的文档位于: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