使用 'json.loads()' 对格式化为字符串的整数进行类型转换
Typecast an integer formatted as a string with 'json.loads()'
我有一个来自 Web 服务器的 JSON 响应,该响应将整数用引号括起来,当使用 Python 的 json
模块加载时,这有效地将它们转换为字符串。
是否有一种聪明的方法可以在 json.loads()
或之后自动转换所有整数和浮点数?
示例数据:
{
u'qualityIndicators':{
u'reviewIndicator':{
u'activeReviewCount':u'229',
u'activePeriodInDays':u'365',
u'reviewsCountedSince':u'2009-02-18',
u'reviewIndicatorPeriodSummary':{
u'reviewIndicatorPeriods':{
u'reviewIndicatorPeriod':{
u'reviewIndicatorMarkSummaries':{
u'reviewIndicatorMarkSummary':[
{
u'markDescription':u'EXCELLENT',
u'periodMarkCount':u'142'
},
{
u'markDescription':u'GOOD',
u'periodMarkCount':u'17'
},
{
u'markDescription':u'FAIR',
u'periodMarkCount':u'12'
},
{
u'markDescription':u'POOR',
u'periodMarkCount':u'22'
},
{
u'markDescription':u'VERY_POOR',
u'periodMarkCount':u'36'
}
]
},
u'startDate':u'2014-03-09',
u'activeReviewCount':u'229',
u'endDate':u'2015-03-09',
u'periodReviewCount':u'229',
u'overallMark':u'3.90',
u'reviewIndicatorCriteria':{
u'reviewIndicatorCriterion':[
{
u'markDescription':u'GOOD',
u'periodCriterionCount':u'224',
u'criterionDescription':u'DELIVERY',
u'mark':u'4.04'
},
{
u'markDescription':u'GOOD',
u'periodCriterionCount':u'219',
u'criterionDescription':u'GOODS',
u'mark':u'4.05'
},
{
u'markDescription':u'GOOD',
u'periodCriterionCount':u'206',
u'criterionDescription':u'SERVICE',
u'mark':u'3.59'
}
]
},
u'overallMarkDescription':u'GOOD'
}
}
},
u'totalReviewCount':u'1911',
u'overallMark':u'3.90',
u'overallMarkDescription':u'GOOD'
}
},
u'targetMarketISO3':u'DEU',
u'url':u'www.zalando.de',
u'tsId':u'X1C77CF6EE730D2E88A284D7203D1B20F',
u'languageISO2':u'de',
u'name':u'zalando.de'
}
一个方法是
def decode(obj):
for k,v in obj.iteritems():
try:
obj[k] = int(v)
except:
pass
return obj
from json import JSONDecoder
d = JSONDecoder(object_hook=decode)
d.decode(<json_string>)
# get raw_data
import json
data = json.loads(raw_data)
def conv_num(data):
if isinstance(data, str):
try:
return json.loads(data)
except ValueError:
return data
elif isinstance(data, list):
ret = []
for v in data:
ret.append(conv_num(v))
return ret
elif isinstance(data, dict):
ret = {}
for k, v in data.items():
ret[k] = conv_num(v)
return ret
else:
return data
data = conv_num(data)
这会将所有整数或浮点数形状的字符串转换为相应的值。
您可以通过继承 json.JSONDecoder
来实现自己的解码器:
import json
def try_casting_to(value, type_):
try:
value = type_(value)
except ValueError:
pass
return value
def try_float(value):
return try_casting_to(value, float)
def try_int(value):
return try_casting_to(value, int)
class NumberDecoder(json.JSONDecoder):
def __init__(self):
json.JSONDecoder.__init__(self, object_hook=self.parse_number)
def parse_number(self, dct):
for key, value in dct.items():
if isinstance(value, basestring):
if '.' in value:
value = try_float(value)
else:
value = try_int(value)
dct[key] = value
return dct
data = """
{"foo": {"baz": {"foo": {"baz": "qux", "bar": "10"}, "bar": "42.5"}}}
"""
obj = NumberDecoder().decode(data)
print obj
输出:
{u'foo': {u'baz': {u'foo': {u'bar': 10, u'baz': u'qux'}, u'bar': 42.5}}}
这只处理 values 中引号中的整数,而不处理 keys 中的整数(尽管更改很简单)。
我有一个来自 Web 服务器的 JSON 响应,该响应将整数用引号括起来,当使用 Python 的 json
模块加载时,这有效地将它们转换为字符串。
是否有一种聪明的方法可以在 json.loads()
或之后自动转换所有整数和浮点数?
示例数据:
{
u'qualityIndicators':{
u'reviewIndicator':{
u'activeReviewCount':u'229',
u'activePeriodInDays':u'365',
u'reviewsCountedSince':u'2009-02-18',
u'reviewIndicatorPeriodSummary':{
u'reviewIndicatorPeriods':{
u'reviewIndicatorPeriod':{
u'reviewIndicatorMarkSummaries':{
u'reviewIndicatorMarkSummary':[
{
u'markDescription':u'EXCELLENT',
u'periodMarkCount':u'142'
},
{
u'markDescription':u'GOOD',
u'periodMarkCount':u'17'
},
{
u'markDescription':u'FAIR',
u'periodMarkCount':u'12'
},
{
u'markDescription':u'POOR',
u'periodMarkCount':u'22'
},
{
u'markDescription':u'VERY_POOR',
u'periodMarkCount':u'36'
}
]
},
u'startDate':u'2014-03-09',
u'activeReviewCount':u'229',
u'endDate':u'2015-03-09',
u'periodReviewCount':u'229',
u'overallMark':u'3.90',
u'reviewIndicatorCriteria':{
u'reviewIndicatorCriterion':[
{
u'markDescription':u'GOOD',
u'periodCriterionCount':u'224',
u'criterionDescription':u'DELIVERY',
u'mark':u'4.04'
},
{
u'markDescription':u'GOOD',
u'periodCriterionCount':u'219',
u'criterionDescription':u'GOODS',
u'mark':u'4.05'
},
{
u'markDescription':u'GOOD',
u'periodCriterionCount':u'206',
u'criterionDescription':u'SERVICE',
u'mark':u'3.59'
}
]
},
u'overallMarkDescription':u'GOOD'
}
}
},
u'totalReviewCount':u'1911',
u'overallMark':u'3.90',
u'overallMarkDescription':u'GOOD'
}
},
u'targetMarketISO3':u'DEU',
u'url':u'www.zalando.de',
u'tsId':u'X1C77CF6EE730D2E88A284D7203D1B20F',
u'languageISO2':u'de',
u'name':u'zalando.de'
}
一个方法是
def decode(obj):
for k,v in obj.iteritems():
try:
obj[k] = int(v)
except:
pass
return obj
from json import JSONDecoder
d = JSONDecoder(object_hook=decode)
d.decode(<json_string>)
# get raw_data
import json
data = json.loads(raw_data)
def conv_num(data):
if isinstance(data, str):
try:
return json.loads(data)
except ValueError:
return data
elif isinstance(data, list):
ret = []
for v in data:
ret.append(conv_num(v))
return ret
elif isinstance(data, dict):
ret = {}
for k, v in data.items():
ret[k] = conv_num(v)
return ret
else:
return data
data = conv_num(data)
这会将所有整数或浮点数形状的字符串转换为相应的值。
您可以通过继承 json.JSONDecoder
来实现自己的解码器:
import json
def try_casting_to(value, type_):
try:
value = type_(value)
except ValueError:
pass
return value
def try_float(value):
return try_casting_to(value, float)
def try_int(value):
return try_casting_to(value, int)
class NumberDecoder(json.JSONDecoder):
def __init__(self):
json.JSONDecoder.__init__(self, object_hook=self.parse_number)
def parse_number(self, dct):
for key, value in dct.items():
if isinstance(value, basestring):
if '.' in value:
value = try_float(value)
else:
value = try_int(value)
dct[key] = value
return dct
data = """
{"foo": {"baz": {"foo": {"baz": "qux", "bar": "10"}, "bar": "42.5"}}}
"""
obj = NumberDecoder().decode(data)
print obj
输出:
{u'foo': {u'baz': {u'foo': {u'bar': 10, u'baz': u'qux'}, u'bar': 42.5}}}
这只处理 values 中引号中的整数,而不处理 keys 中的整数(尽管更改很简单)。