2

I'm trying to get a series of serialized dictionaries where only one specific value changes.

the ficticious python dict named "obj"

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

should "work" like this:

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

is there a way I can archive this?

It would also be ok to do something like this:

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

should "work" like this

>>> <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}}}
Daniel F
  • 13,684
  • 11
  • 87
  • 116
  • 1
    Does it have to work with barebones `json.dumps`? Using a custom encoder or specifying a `default` function could easily replace a generator with its current value. – user4815162342 Nov 19 '14 at 22:27

3 Answers3

3
import json

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

for obj in _gen:
    print json.dumps(obj)

Running yields:

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

You can wrap up the generator expression in a function:

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)
Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
  • damn, can't use this, as I need to be able to pass _gen into a function, as _gen will exist before the dict has been created. This will force me to use spicavigo's answer. I'm sorry for removing the accept. – Daniel F Nov 19 '14 at 22:41
3

Here is a solution

import 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)

You can run the code on CodeBunk http://codebunk.com/b/49813922/

spicavigo
  • 4,116
  • 22
  • 28
3

Actually this turned out to be the best answer. Even though I'm not feeling well about answering my own question.

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)
Daniel F
  • 13,684
  • 11
  • 87
  • 116