簡體   English   中英

Python JSONDecoder自定義null類型的轉換

[英]Python JSONDecoder custom translation of null type

在python中,默認情況下,JSONDecoder會將null的轉換預設為None,如下所示。 如何將null - > None的轉換更改為不同的轉換。 即null - >'貓'

class json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])

Simple JSON decoder.

Performs the following translations in decoding by default:
  JSON  Python
  object    dict
  array     list
  string    unicode
  number (int)  int, long
  number (real)     float
  true  True
  false     False
  null  None

我想要 json.loads({“field1”:null,“field2”:“data!”})

返回 {u'field2':u'data!',u'field1':u'Cat'}

更新12/30/2014

實現這一目標的最簡單方法是使用object_hook的回調JSONDecoder正如我在下面舊的答案描述。 但是,由於這需要對數據中的每個鍵值對進行額外的函數調用,這可能會對性能產生影響。

所以,如果你真的想改變json處理None的方式,你需要深入挖掘一下。 JSONDecoder使用掃描程序在JSON輸入中查找某些令牌。 不幸的是,這是一個函數,而不是一個類,因此子類化並不那么容易。 掃描儀功能稱為py_make_scanner ,可以在json / py_make_scanner中找到。 它基本上是一個函數,它將JSONDecoder作為參數獲取並返回scan_once函數。 scan_once函數接收字符串和當前掃描儀位置的索引。

一個簡單的自定義掃描儀功能可能如下所示:

import json

def make_my_scanner(context):
    # reference to actual scanner
    interal_scanner = json.scanner.py_make_scanner(context)

    # some references for the _scan_once function below
    parse_object = context.parse_object
    parse_array = context.parse_array
    parse_string = context.parse_string
    encoding = context.encoding
    strict = context.strict
    object_hook = context.object_hook
    object_pairs_hook = context.object_pairs_hook

    # customized _scan_once
    def _scan_once(string, idx):
        try:
            nextchar = string[idx]
        except IndexError:
            raise StopIteration

        # override some parse_** calls with the correct _scan_once
        if nextchar == '"':
            return parse_string(string, idx + 1, encoding, strict)
        elif nextchar == '{':
            return parse_object((string, idx + 1), encoding, strict,
                _scan_once, object_hook, object_pairs_hook)
        elif nextchar == '[':
            return parse_array((string, idx + 1), _scan_once)
        elif nextchar == 'n' and string[idx:idx + 4] == 'null':
            return 'Cat', idx + 4

        # invoke default scanner
        return interal_scanner(string, idx)

    return _scan_once

現在我們只需要一個JSONDecoder子類,它將使用我們的掃描器而不是默認掃描器:

class MyJSONDecoder(json.JSONDecoder):
    def __init__(self, encoding=None, object_hook=None, parse_float=None,
            parse_int=None, parse_constant=None, strict=True,
            object_pairs_hook=None):

        json.JSONDecoder.__init__(self, encoding, object_hook, parse_float, parse_int, parse_constant, strict, object_pairs_hook)

        # override scanner
        self.scan_once = make_my_scanner(self)

然后像這樣使用它:

decoder = MyJSONDecoder()
print decoder.decode('{"field1":null, "field2": "data!"}')

舊的答案,但如果你不關心另一個函數調用的性能影響仍然有效:

您需要使用特殊的object_hook方法創建JSONDecoder對象:

import json

def parse_object(o):
    for key in o:
        if o[key] is None:
            o[key] = 'Cat'
    return o

decoder = json.JSONDecoder(object_hook=parse_object)

print decoder.decode('{"field1":null, "field2": "data!"}')
# that will print: {u'field2': u'data!', u'field1': u'Cat'}

根據json模塊Python文檔

object_hook是一個可選函數,將使用任何對象文字解碼(dict)的結果調用。 將使用object_hook的返回值而不是dict。

所以parse_object將獲得一個字典,可以通過用'Cat'交換所有None值來操作。 然后將在輸出中使用返回的對象/字典。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM