2013-09-21 34 views
1

json.dumps使用科學記數法輸出小浮點值或十進制值,這是發送到json-rpc應用程序不可接受的。在python中禁用科學記數法json.dumps輸出

>>> import json 
>>> json.dumps({"x": 0.0000001}) 
'{"x": 1e-07}' 

我想這個輸出,而不是:

'{"x": 0.0000001}' 

這將是理想的,以避免引入額外的依賴。

+2

我會毫不猶豫地稱之爲 「JSON-RPC」 應用程序,如果它沒有真正理解[JSON](HTTP ://json.org/)... –

+0

或漂浮在那裏...... – tacaswell

+0

你唯一的選擇就是將它轉換爲一個字符串。這會工作嗎? –

回答

1

一個格式化

evil = {"x": 0.00000000001} 

方式是竊取Decimal的 「F」 格式。這是我發現的避免裁剪問題和指數的唯一簡單方法,但它的效率並不高,而且空間效率也很高。

class FancyFloat(float): 
    def __repr__(self): 
     return format(Decimal(self), "f") 

要使用它,你就可以說「decimalize」 S輸入

class JsonRpcEncoder(json.JSONEncoder): 
    def decimalize(self, val): 
     if isinstance(val, dict): 
      return {k:self.decimalize(v) for k,v in val.items()} 

     if isinstance(val, (list, tuple)): 
      return type(val)(self.decimalize(v) for v in val) 

     if isinstance(val, float): 
      return FancyFloat(val) 

     return val 

    def encode(self, val): 
     return super().encode(self.decimalize(val)) 

JsonRpcEncoder().encode(evil) 
#>>> '{"x": 0.00000000000999999999999999939496969281939810930172340963650867706746794283390045166015625}' 

或者,當然,你可以從移動到十進制的函數和調用json.dumps之前的編碼器。

這就是我會這麼做的,即使這是一種蹩腳的方法。

0

某處發現在互聯網上

import json 
from json import encoder 
encoder.FLOAT_REPR = lambda o: format(o, '.2f') 

在此之後

>>> json.dumps({'gps': [51.5, 17.5]}) 
'{"gps": [51.5, 17.5]}'