Python Twisted Defer returnValue 与 dict 不兼容

Python Twisted Defer returnValue incompatible with dict

我在我的包中广泛使用 twisted.internet.defer,我遇到了一个问题,我花了 2 天时间解决不了。以下是我的问题场景。

# all imports done and correct
class infrastructure: # line 1

  @inlineCallbacks
  def dict_service(self):
    client = MyClient()
    services = yield client.listServices() # line 5
    ret = (dict(service.name, [cont.container_id for cont in service.instances]) for service in dockerServices)
    returnValue(ret) # line 7

我打电话给我的客户,return是我的服务列表。 listServices() return 类型是 twisted.internet.defer.ReturnValue

class myinterface:
   # has infrastructure

  def init:
     data = dict(
        container_services=self._infrastructure.dict_service(),
        )

执行此操作时出现以下错误,我无法理解。有人可以帮忙吗

raise TypeError(repr(o) + \" is not JSON serializable\")\nexceptions.TypeError: <DeferredWithContext at 0x4bfbb48 current result: <twisted.python.failure.Failure <type 'exceptions.NameError'>>> is not JSON serializable\n"

是不是因为用 returnValue 包装 dict 造成了问题?

使用 returnValuedict 实例没有问题:

$ python -m twisted.conch.stdio
>>> from __future__ import print_function
>>> from twisted.internet.defer import inlineCallbacks, returnValue
>>> @inlineCallbacks
... def f():
...     d = yield {"foo": "bar"} # Yield *something* or it's not a generator
...     returnValue(d)
... 
>>> f().addCallback(print)
{'foo': 'bar'}
<Deferred at 0x7f84c51847a0 current result: None>

您报告的错误:

raise TypeError(repr(o) + \" is not JSON serializable\")\nexceptions.TypeError: <DeferredWithContext at 0x4bfbb48 current result: <twisted.python.failure.Failure <type 'exceptions.NameError'>>> is not JSON serializable\n"

让它看起来好像您有一些代码可以触发 NameError。这似乎发生在延迟回调中(或以其他方式进入延迟回调)并被包裹在 Failure:

<twisted.python.failure.Failure <type 'exceptions.NameError'>>

剩下:

raise TypeError(repr(o) + \" is not JSON serializable\")\nexceptions.TypeError: <DeferredWithContext at 0x4bfbb48 current result: ...> is not JSON serializable\n"

我不知道 DeferredWithContext 是什么。我猜它是 Deferred 的子类,具有一些额外的行为。如果您可以 link 访问提供此功能的库,那就太好了(对我来说这似乎是个坏主意,但我想了解更多)。

如果是这样,那么错误是关于一个 DeferredWithContext 实例,它的结果是 above-described Failure

<DeferredWithContext at 0x4bfbb48 current result: ...>

剩下:

raise TypeError(repr(o) + \" is not JSON serializable\")\nexceptions.TypeError: ... is not JSON serializable\n"

这似乎来自 json 模块,dumpdumps 函数。这是在声明传入的不是 JSON 可序列化的内容。DeferredWithContext 几乎肯定不是 JSON 可序列化的,所以这就解释了问题。

这可能是由于:

json.dumps(function_that_returns_deferred())

应该改为:

function_that_returns_deferred().addCallback(json.dumps)