我有一堆要转换为JSON对象字符串的变量。其中一些变量是集合。但是,如果这些集合只有一个条目,我将无法正常工作。
我已经看过以下问题,但是我不使用文字,而是使用变量。所以对我真的没有帮助。
How to pass a list containing a single string in python?
我尝试使用以下类对数据进行编码:
class SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
setLen = len(obj)
if len(obj) != 1:
setAsList = list(obj)
else:
setAsList = [obj]
logging.debug("DIAG: IN SetEncoder with obj = %r ; setAsList = %r ; setLen = %s" % (obj, setAsList, setLen))
return setAsList
return json.JSONEncoder.default(self, obj)
这是我尝试编码Set的代码:
# following is just to demonstrate the problem; no matter how I try to
# set the single element set, the code to process it doesn't work;
# I've tried set(("CAT1")), set(("CAT1",)), set(["CAT1",])
countriesSet = set(["US", "DE"])
categoriesSet = set(["CAT1"])
body = {
"ownerId": OWNER_ID,
"countries": countriesSet,
"categories": categoriesSet
}
bodyJson = json.dumps(body, cls=SetEncoder)
这是我的输出:
DEBUG:root:DIAGDIAGDIAG: countriesSet = {'US', 'DE'}, len = 2; categoriesSet = {'CAT1'}, len = 1
DEBUG:root:DIAG: IN SetEncoder with obj = {'US', 'DE'} ; setAsList = ['US', 'DE'] ; setLen = 2
DEBUG:root:DIAG: IN SetEncoder with obj = {'CAT1'} ; setAsList = [{'CAT1'}] ; setLen = 1
ERROR:root:parseXML: Encountered exception - Circular reference detected for destination <Element 'destination' at 0x000002570535B728>
如您所见,单个条目周围有花括号,而工作条目则没有。
有人有什么想法吗?
答案 0 :(得分:2)
简单怎么了?
class SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return json.JSONEncoder.default(self, obj)
通过[x]
,您可以将设置的对象包装在列表中,而不是“转换”它。 (正是这种包装的展开导致了循环引用)
回复:讨论
我们很清楚,这就是我的建议。在任何情况下,我都不会丢失单个元素(列表/元组/集合)周围的括号: 导入json
class SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return json.JSONEncoder.default(self, obj)
objs = {
'one_element_list_int': [1],
'one_element_list_tup': ("foo",),
'one_element_list_set': {10},
'two_element_list_int': [2, 3],
'two_element_list_tup': ("bar", "baz"),
'two_element_list_set': {11,12},
}
for (k,v) in objs.items():
dump = json.dumps(v, cls=SetEncoder)
print(k+": ", v, "->", dump)
生产
one_element_list_int: [1] -> [1] one_element_list_tup: ('foo',) -> ["foo"] one_element_list_set: {10} -> [10] two_element_list_int: [2, 3] -> [2, 3] two_element_list_tup: ('bar', 'baz') -> ["bar", "baz"] two_element_list_set: {11, 12} -> [11, 12]