【问题标题】:json.dump a concurrent.futures.Future()?json.dump 一个 concurrent.futures.Future()?
【发布时间】:2016-01-19 14:21:13
【问题描述】:

假设我有一些未来:

f = concurrent.futures.Future()
data = [f]

最终我想将这些转储到 JSON 中,并且我保证到那时期货已经解决:

f.set_result(42)
json.dumps(data)

我怎样才能把这两个结婚?

【问题讨论】:

  • 我有一个 hack 可以覆盖 jsonEncoder 类,但是否有更好的解决方案?

标签: python json python-3.x future


【解决方案1】:

重写 JSONEncoder 类并在 Future 实例上调用 o.result() 是一种方法。

class CustomJSONEncoder(json.JSONEncoder):
    def default(self, o, *args, **kwargs):
        if isinstance(o, concurrent.futures.Future):
            return o.result()
        return super(CustomJSONEncoder, self).default(o, *args, **kwargs)

json.dumps(data, cls=CustomJSONEncoder)

要使其在没有自定义 JSONEncoder 的情况下工作,您可以自己遍历数据结构,调用 o.result():

data = [o.result() if isinstance(o, concurrent.futures.Future) else o for o in data]

或者在原地修改data

for i, o in enumerate(data):
    if isinstance(o, concurrent.futures.Future):
        data[i] = o.result()

【讨论】:

  • 我认为您正在对return o.result 中的结果表示做出假设——这是否也需要通过super().default() 传递?事实上,也许最好递归调用return self.default(o.result),以防result 是一个容器,其中有另一个已解决的未来?
  • 你只需要调用super().default()来提高TypeError:docs.python.org/2/library/json.html#json.JSONEncoder.default
  • 如果o.result() 是可迭代的并且您将其返回,它仍应正确序列化。我检查了 Python 源代码以确保 default() 返回的任何内容都经过常规序列化过程。
【解决方案2】:
json.dumps([d.result() for d in data])

【讨论】:

  • 很好,但前提是呼叫站点具有数据模型知识。我宁愿有一些通用的东西。
  • 创建一个 JSON 感知的 Future 子类?大概只需要覆盖 str 就可以调用self.result()?
猜你喜欢
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-06
  • 2014-04-22
  • 2019-06-03
  • 2014-03-08
  • 2017-10-08
  • 1970-01-01
相关资源
最近更新 更多