【问题标题】:Evaluating dictionary value during json serialization在 json 序列化期间评估字典值
【发布时间】:2015-01-17 15:17:46
【问题描述】:

我正在尝试获取一系列序列化字典,其中只有一个特定值发生变化。

名为“obj”的虚构python字典

_gen = (value for value in range(5,10))
obj = {'mcu': {'led0': {'duty': _gen}}}

应该像这样“工作”:

>>> json.dumps(obj)
'{"mcu":{"led0":{"duty": 5}}}
>>> json.dumps(obj)
'{"mcu":{"led0":{"duty": 6}}}
>>> json.dumps(obj)
'{"mcu":{"led0":{"duty": 7}}}

有办法存档吗?

也可以这样做:

_placeholder = <some trick to create a placeholder>
obj = {'mcu': {'led0': {'duty': _placeholder}}}

应该像这样“工作”

>>> <placeholder modification trick> = 5
>>> json.dumps(obj)
'{"mcu":{"led0":{"duty": 5}}}
>>> <placeholder modification trick> = 6
>>> json.dumps(obj)
'{"mcu":{"led0":{"duty": 6}}}
>>> <placeholder modification trick> = 7
>>> json.dumps(obj)
'{"mcu":{"led0":{"duty": 7}}}

【问题讨论】:

  • 它是否必须与准系统 json.dumps 一起使用?使用自定义编码器或指定default 函数可以轻松地将生成器替换为其当前值。

标签: python json serialization dictionary lazy-evaluation


【解决方案1】:

事实上,这是最好的答案。尽管我对回答自己的问题感到不舒服。

import json
import types

_gen = (value for value in range(5, 10))
property = {'mcu':{'led0':{'duty': _gen}}}

def generator_handler(obj):
    if isinstance(obj, types.GeneratorType):
      return obj.next()
    else:
      return None

print json.dumps(property, default=generator_handler)
print json.dumps(property, default=generator_handler)
print json.dumps(property, default=generator_handler)

【讨论】:

    【解决方案2】:

    这里有一个解决方案

    导入 json

    class Gen(object):
        def __init__(self):
            self.x = 1
        def next(self):
            self.x+=1
            return self.x
    
    class Gencoder(json.JSONEncoder):
        def default(self, obj):
            if isinstance(obj, Gen):
                return obj.next()
            return json.JSONEncoder.default(self, obj)
    
    _gen = Gen()
    print json.dumps({'mcu': {'led0': {'duty': _gen}}}, cls=Gencoder)
    print json.dumps({'mcu': {'led0': {'duty': _gen}}}, cls=Gencoder)
    print json.dumps({'mcu': {'led0': {'duty': _gen}}}, cls=Gencoder)
    print json.dumps({'mcu': {'led0': {'duty': _gen}}}, cls=Gencoder)
    

    您可以在 CodeBunk http://codebunk.com/b/49813922/ 上运行代码

    【讨论】:

    • 我正打算用这个作为接受的答案,但想出了一个更短的答案,它实际上使用了一个生成器。
    • @DanielF 我也为这个答案 +1 :)
    【解决方案3】:
    import json
    
    _gen = ({'mcu': {'led0': {'duty': value}}} for value in range(5, 10))
    
    for obj in _gen:
        print json.dumps(obj)
    

    运行产量:

    $ python gen.py
    {"mcu": {"led0": {"duty": 5}}}
    {"mcu": {"led0": {"duty": 6}}}
    {"mcu": {"led0": {"duty": 7}}}
    {"mcu": {"led0": {"duty": 8}}}
    {"mcu": {"led0": {"duty": 9}}}
    

    您可以将生成器表达式包装在一个函数中:

    import json
    
    def generate_generator(a, b):
        return ({'mcu': {'led0': {'duty': value}}} for value in range(a, b))
    
    for obj in generate_generator(2, 7):
        print json.dumps(obj)
    

    【讨论】:

    • 该死,不能使用这个,因为我需要能够将 _gen 传递给一个函数,因为 _gen 将在创建字典之前存在。这将迫使我使用 spicavigo 的答案。很抱歉删除了接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    相关资源
    最近更新 更多