2

当我使用带扭曲的延迟函数时,参数让我很困惑。

我考虑如果函数的参数是INT-VALUE,或者除了 list 和 dict 之外的其他基本类型,它应该传递值而不是引用。

from twisted.internet import defer, reactor

def deferFunc(x):
    print "11111 %d" % x
    d = defer.Deferred()
    reactor.callLater(1, d.callback, x)
    return d

@defer.inlineCallbacks
def inlineDeferFunc(x):
    print "11111 %d" % x
    d = defer.Deferred()
    reactor.callLater(1, d.callback, x)
    result = yield d
    defer.returnValue(result)

def loop():
    x = [1,2,3,4]
    d = defer.succeed(0)
    for i in x:
        d.addCallback(lambda _ : inlineDeferFunc(i))

if __name__ == '__main__':
    loop()

    try:
        reactor.run()
    except:
        reactor.stop()

结果是:

11111 1
11111 4
11111 4
11111 4

结果让我很困惑。

我怎样才能得到正确的输出,如 1,2,3,4

4

1 回答 1

3

我怎样才能得到正确的输出,如 1,2,3,4

像这样:

def loop():
    x = [1,2,3,4]
    d = defer.succeed(0)
    for i in x:
        d.addCallback(lambda _, i = i : inlineDeferFunc(i))



11111 1
11111 2
11111 3
11111 4

请注意,我们正在复制函数定义中的值i = i
问题是,毕竟它会如何知道它是什么值,但由于性能原因,我认为它不会在定义过程中复制它,但父环境会不断更新lambda循环。ifor

这是一个简单的测试。

>>> def test_closures():
...     i = 2
...     def test():
...         return i
...     i = 3
...     return test
... 
>>> test_closures()()
3
于 2012-07-15T02:57:49.303 回答