科学记数法和从 DB 输出到 Python 中 JSON 的转换
Posted
技术标签:
【中文标题】科学记数法和从 DB 输出到 Python 中 JSON 的转换【英文标题】:Scientific Notation and conversions from DB output into JSON in Python 【发布时间】:2017-12-08 23:42:45 【问题描述】:我正在编写 python 代码来测试 REST 端点以从数据库中获取科学数字,并验证科学格式是否以正确的 JSON 科学数字格式从数据库返回。
我遇到的问题是一些科学数字被转换了。例如,JSON 加载器会将 e 转换为大写,并且将一些值转换为整数。这是一些示例代码。由于您没有数据库后端,因此代码并没有完全按照我正在做的事情。
import json
import decimal
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
print 'In here: ' + str( o )
return str(o)
return super(DecimalEncoder, self).default(o)
class JSONUtils:
def __init__( self, response ):
self.response = response
self.jsonData = None
self.LoadData( )
# print 'jsonData: ' + json.dumps( self.jsonData, cls=DecimalEncoder, indent=2 )
def GetData( self ):
return self.jsonData
def GetAsStr( self ):
return json.dumps(self.GetData(), cls=DecimalEncoder )
def LoadData ( self ):
if ( self.jsonData == None ):
if ( type( self.response ) == str or type( self.response ) == unicode ):
print '****type1'
self.jsonData = json.loads(self.response, parse_float=decimal.Decimal )
elif ( type( self.response ) == dict ):
print '****type2'
dump = json.dumps( self.response, cls=DecimalEncoder )
self.jsonData = json.loads(dump, parse_float=decimal.Decimal)
def GetJSONChunk( self, path ):
returnValue = ''
curPath = ''
try:
if ( type( path ) == str ):
returnValue = self.jsonData[path]
elif (type( path ) == list):
temp = ''
firstTime = True
for curPath in path:
if firstTime == True:
temp = self.jsonData[curPath]
firstTime = False
else:
temp = temp[curPath]
returnValue = temp
else:
print 'Unknown type in GetJSONChunk: ' + unicode( type( path ))
except KeyError as err:
ti.DBG_OUT( 'JSON chunk doesn\'t have value: ' + unicode( path ))
returnValue = self.kNoNode
except IndexError as err:
ti.DBG_OUT( 'Index does not exist: ' + unicode( curPath ))
returnValue = self.kInvalidIndex
return returnValue
info = "fldName":1.47e-10 # converts to 1.47e-10 (e to E)
# info = "fldName":1.47e10 # convers to 14700000000.0
# info = "fldName":1.47e+10 # convers to 14700000000.0
# info = "fldName":1.47E+10 # convers to 14700000000.0
# info = "fldName":12345678901234567890123 # example shows larger # support
print 'info: ' + str ( info )
myJSON = JSONUtils( info )
print 'type: ' + str( myJSON.jsonData )
print 'myJSON: ' + myJSON.GetAsStr( )
value = myJSON.GetJSONChunk ( 'fldName' )
print 'Type: ' + str( type( value ))
print value
我需要做的是将数据库结果与预期值进行比较。有没有办法只识别科学数字?不加倍/十进制值并将它们作为字符串返回。如您所见,我已经在尝试保护返回的 Doubles,以确保满足后端数据库的标准/功能。可以是小数点左边或右边的 20+ 位。
以#info 开头的每一行代码都记录了实际结果。
【问题讨论】:
【参考方案1】:我对你的问题并不完全清楚,所以如果这太离谱了,请告诉我。
我认为 Python 显示数字的方式与数字的实际值之间可能存在一些混淆。
例如,我可以将数字 1000 写为:
>>> 1000
1000.0
>>> 1E3
1000.0
>>> 10E2
1000.0
>>> 1e3
1000.0
>>> 1e+3
1000.0
这些都是数字的不同表示,但它们在数字上都是等价的。 JSON 也同样灵活;所有上述表示在 JSON 中也是有效的。
同样,我可以写:
10000000000000000000000000000.0
但print
语句会将其显示为:
1e+28
但它仍然是相同的数字。它没有以任何方式“转换”。一旦你的号码是>= 1E16
,Python 将使用 E 表示法。
因此,如果我收到如下所示的 JSON:
"val1": 1e+3,
"val2": 1e+20
以下输出:
values = json.loads('"val1": 1e+3, "val2": 1e+20')
for k, v in values.items():
print(k, '=', v)
应该是:
val1 = 1000.0
val2 = 1e+20
【讨论】:
我知道您可以将数字表示为整数或科学计数法中的相同数字。我正在测试从数据库返回的科学值并检查它们的准确性。 IOW:数据库是否正确表示数字/科学数字。无论如何,我不希望价值观受到影响。正在发生的事情是数据库将返回一个有效的科学值,并且执行 JSON 加载将导致该值被转换。是的...对于有效的科学表示,但我需要原始值而不是经过处理的值。任何想法将不胜感激。以上是关于科学记数法和从 DB 输出到 Python 中 JSON 的转换的主要内容,如果未能解决你的问题,请参考以下文章
GraphQL 和从 Oracle DB 中提取数据:查询以结果集响应并且不进入 Graphql 解析器窗口