科学记数法和从 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 解析器窗口

当我在 coursera 中使用 python 在数据科学中运行以下代码时出错

bzoj4514 数字配对

python 输出数字,如何不以科学计数法输出?

破坏者模式 - 主节点和从节点如何保持同步?

强制python不以标准形式/科学记数法/指数形式输出浮点数[重复]