web-dev-qa-db-fra.com

Comment obtenir des objets chaîne au lieu d'Unicode à partir de JSON?

J'utilise Python 2 pour analyser JSON à partir de fichiers texte codés ASCII

Lors du chargement de ces fichiers avec json ou simplejson , toutes mes valeurs de chaîne sont converties en objets Unicode au lieu d'objets chaîne. Le problème est que je dois utiliser les données avec certaines bibliothèques qui n'acceptent que les objets chaîne. Je ne peux pas changer les bibliothèques ni les mettre à jour.

Est-il possible d'obtenir des objets chaîne au lieu de ceux Unicode?

Exemple

>>> import json
>>> original_list = ['a', 'b']
>>> json_list = json.dumps(original_list)
>>> json_list
'["a", "b"]'
>>> new_list = json.loads(json_list)
>>> new_list
[u'a', u'b']  # I want these to be of type `str`, not `unicode`

Mettre à jour

Cette question a été posée il y a longtemps}, lorsque j'étais coincé avec Python 2. Une solution simple et propre pour aujourd’hui consiste à utiliser une version récente de Python, à savoir Python 3 et suivante.

255
Brutus

Une solution avec object_hook

import json

def json_load_byteified(file_handle):
    return _byteify(
        json.load(file_handle, object_hook=_byteify),
        ignore_dicts=True
    )

def json_loads_byteified(json_text):
    return _byteify(
        json.loads(json_text, object_hook=_byteify),
        ignore_dicts=True
    )

def _byteify(data, ignore_dicts = False):
    # if this is a unicode string, return its string representation
    if isinstance(data, unicode):
        return data.encode('utf-8')
    # if this is a list of values, return list of byteified values
    if isinstance(data, list):
        return [ _byteify(item, ignore_dicts=True) for item in data ]
    # if this is a dictionary, return dictionary of byteified keys and values
    # but only if we haven't already byteified it
    if isinstance(data, dict) and not ignore_dicts:
        return {
            _byteify(key, ignore_dicts=True): _byteify(value, ignore_dicts=True)
            for key, value in data.iteritems()
        }
    # if it's anything else, return it in its original form
    return data

Exemple d'utilisation:

>>>json_loads_byteified('{"Hello": "World"}')
{'Hello': 'World'}
>>>json_loads_byteified('"I am a top-level string"')
'I am a top-level string'
>>>json_loads_byteified('7')
7
>>>json_loads_byteified('["I am inside a list"]')
['I am inside a list']
>>>json_loads_byteified('[[[[[[[["I am inside a big nest of lists"]]]]]]]]')
[[[[[[[['I am inside a big nest of lists']]]]]]]]
>>>json_loads_byteified('{"foo": "bar", "things": [7, {"qux": "baz", "moo": {"cow": ["milk"]}}]}')
{'things': [7, {'qux': 'baz', 'moo': {'cow': ['milk']}}], 'foo': 'bar'}
>>>json_load_byteified(open('somefile.json'))
{'more json': 'from a file'}

Comment cela fonctionne-t-il et pourquoi l'utiliser?

La fonction de Mark Amery est plus courte et plus claire que celles-ci, alors à quoi ça sert? Pourquoi voudriez-vous les utiliser?

Purement pour performance. La réponse de Mark décode entièrement le texte JSON d'abord avec des chaînes unicode, puis revient à travers la valeur décodée complète pour convertir toutes les chaînes en chaînes d'octets. Cela a quelques effets indésirables:

  • Une copie de la structure entière décodée est créée en mémoire
  • Si votre objet JSON est vraiment profondément imbriqué (500 niveaux ou plus), vous atteindrez la profondeur de récursivité maximale de Python.

Cette réponse atténue ces deux problèmes de performances en utilisant le paramètre object_hook de json.load et json.loads. De les docs :

object_hook est une fonction facultative appelée avec le résultat de tout objet littéral décodé (une dict). La valeur de retour de object_hook sera utilisée à la place de dict. Cette fonctionnalité peut être utilisée pour implémenter des décodeurs personnalisés

Étant donné que les dictionnaires qui ont imbriqué de nombreux niveaux au sein d’autres dictionnaires sont passés à object_hookau fur et à mesure qu’ils sont décodés, nous pouvons spécifier toutes les chaînes ou listes qu’ils contiennent à ce moment-là et éviter d’avoir besoin d’une récursion profonde plus tard.

La réponse de Mark ne peut pas être utilisée en tant que object_hook telle quelle, car elle rentre dans des dictionnaires imbriqués. Nous évitons cette récursion dans cette réponse avec le paramètre ignore_dicts à _byteify, qui lui est toujours transmis sauf lorsque object_hook lui transmet une nouvelle variable dict à octroyer. L'indicateur ignore_dicts indique à _byteify d'ignorer les dicts puisqu'elles ont déjà été octroyées.

Enfin, nos implémentations de json_load_byteified et json_loads_byteified appellent _byteify (avec ignore_dicts=True) sur le résultat renvoyé par json.load ou json.loads pour traiter le cas où le texte JSON en cours de décodage ne comporte pas de dict au niveau supérieur.

89
Mirec Miskuf

Bien qu'il y ait de bonnes réponses ici, j'ai fini par utiliser PyYAML pour analyser mes fichiers JSON, car il donne les clés et les valeurs sous forme de chaînes de type str au lieu de type unicode. Parce que JSON est un sous-ensemble de YAML, cela fonctionne bien:

>>> import json
>>> import yaml
>>> list_org = ['a', 'b']
>>> list_dump = json.dumps(list_org)
>>> list_dump
'["a", "b"]'
>>> json.loads(list_dump)
[u'a', u'b']
>>> yaml.safe_load(list_dump)
['a', 'b']

Remarques

Quelques points à noter cependant:

  • Je reçois objets de chaîne car toutes mes entrées sont ASCII codées. Si j'utilisais des entrées codées unicode, je les récupérerais sous forme d'objets unicode - il n'y a pas de conversion!

  • Vous devriez (probablement toujours) utiliser la fonction safe_load de PyYAML; si vous l'utilisez pour charger des fichiers JSON, vous n'avez de toute façon pas besoin de la "puissance supplémentaire" de la fonction load.

  • Si vous voulez un analyseur YAML qui supporte davantage la version 1.2 de la spécification (et analyse correctement les nombres très faibles ), essayez Ruamel YAML : pip install ruamel.yaml et import ruamel.yaml as yaml était tout ce dont j'avais besoin dans mon tests.

Conversion

Comme indiqué, il n'y a pas de conversion! Si vous ne pouvez pas être sûr de ne traiter que les valeurs ASCII (et vous ne pouvez pas être sûr la plupart du temps), il vaut mieux utiliser une fonction conversion:

J'ai utilisé celui de Mark Amery plusieurs fois maintenant, il fonctionne très bien et est très facile à utiliser. Vous pouvez également utiliser une fonction similaire en tant que object_hook, car cela pourrait vous permettre d'améliorer les performances des gros fichiers. Voir le réponse de Mirec Miskuf légèrement plus impliqué pour cela.

169
Brutus

Il n’existe pas d’option intégrée permettant aux fonctions du module JSON de renvoyer des chaînes d’octets au lieu de chaînes Unicode. Cependant, cette fonction récursive simple et courte convertira tout objet JSON décodé de l'utilisation de chaînes unicode en chaînes d'octets codées en UTF-8:

def byteify(input):
    if isinstance(input, dict):
        return {byteify(key): byteify(value)
                for key, value in input.iteritems()}
    Elif isinstance(input, list):
        return [byteify(element) for element in input]
    Elif isinstance(input, unicode):
        return input.encode('utf-8')
    else:
        return input

Appelez simplement ceci sur la sortie que vous obtenez à partir d'un appel json.load ou json.loads.

Quelques notes:

  • Pour prendre en charge Python 2.6 ou version antérieure, remplacez return {byteify(key): byteify(value) for key, value in input.iteritems()} par return dict([(byteify(key), byteify(value)) for key, value in input.iteritems()]), car la compréhension du dictionnaire n’était prise en charge que jusqu’à Python 2.7.
  • Etant donné que cette réponse se répète dans l’ensemble de l’objet décodé, elle présente quelques caractéristiques de performances indésirables qui peuvent être évitées grâce à une utilisation très prudente des paramètres object_hook ou object_pairs_hook. La réponse de Mirec Miskuf est jusqu'à présent la seule à réussir à tirer cela correctement, bien qu'en conséquence, c'est beaucoup plus compliqué que mon approche.
139
Mark Amery

Vous pouvez utiliser le paramètre object_hook pour json.loads pour transmettre un convertisseur. Vous n'êtes pas obligé de faire la conversion après coup. Le module json ne transmettra toujours que les codes object_hook et il passera de manière récursive dans les dictons imbriqués, de sorte que vous n’aurez pas à récurer vous-même dans les dict imbriqués. Je ne pense pas que je convertirais des chaînes unicode en nombres comme le montre Wells. S'il s'agit d'une chaîne unicode, elle a été citée en tant que chaîne dans le fichier JSON. Elle est donc supposée être une chaîne (ou le fichier est incorrect).

De plus, j'essaierais d'éviter de faire quelque chose comme str(val) sur un objet unicode. Vous devez utiliser value.encode(encoding) avec un encodage valide, en fonction de ce que votre librairie externe attend.

Donc, par exemple:

def _decode_list(data):
    rv = []
    for item in data:
        if isinstance(item, unicode):
            item = item.encode('utf-8')
        Elif isinstance(item, list):
            item = _decode_list(item)
        Elif isinstance(item, dict):
            item = _decode_dict(item)
        rv.append(item)
    return rv

def _decode_dict(data):
    rv = {}
    for key, value in data.iteritems():
        if isinstance(key, unicode):
            key = key.encode('utf-8')
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        Elif isinstance(value, list):
            value = _decode_list(value)
        Elif isinstance(value, dict):
            value = _decode_dict(value)
        rv[key] = value
    return rv

obj = json.loads(s, object_hook=_decode_dict)
73
Mike Brennan

En effet, json n'a aucune différence entre les objets chaîne et les objets unicode. Ce sont toutes des chaînes en javascript.

Je pense que JSON a raison de renvoyer des objets unicode . En fait, je n'accepterais rien de moins, car les chaînes javascript sont en fait des objets unicode(c'est-à-dire que les chaînes JSON (javascript) peuvent stocker tout type de caractères unicode), il est donc logique de créer unicode objets lors de la traduction de chaînes à partir de JSON. Les chaînes de caractères ordinaires ne correspondraient tout simplement pas, car la bibliothèque devrait deviner le codage souhaité.

Il est préférable d'utiliser des objets chaîne unicode string partout. Votre meilleure option consiste donc à mettre à jour vos bibliothèques afin qu’elles puissent traiter les objets unicode.

Mais si vous voulez vraiment des bytestrings, encodez simplement les résultats avec l'encodage de votre choix:

>>> nl = json.loads(js)
>>> nl
[u'a', u'b']
>>> nl = [s.encode('utf-8') for s in nl]
>>> nl
['a', 'b']
37
nosklo

Il existe un moyen facile de contourner le problème.

TL; DR - Utilisez ast.literal_eval() au lieu de json.loads(). ast et json sont tous deux dans la bibliothèque standard.

Bien que ce ne soit pas une réponse «parfaite», il en va assez bien si vous envisagez d'ignorer complètement Unicode. En Python 2.7

import json, ast
d = { 'field' : 'value' }
print "JSON Fail: ", json.loads(json.dumps(d))
print "AST Win:", ast.literal_eval(json.dumps(d))

donne:

JSON Fail:  {u'field': u'value'}
AST Win: {'field': 'value'}

Cela devient plus poilu lorsque certains objets sont vraiment des chaînes Unicode. La réponse complète devient rapidement poilue.

15
Charles Merriam

La réponse de Mike Brennan est proche, mais il n'y a aucune raison de re-traverser la structure entière. Si vous utilisez le paramètre object_hook_pairs (Python 2.7+):

object_pairs_hook est une fonction facultative appelée avec le résultat de tout littéral d'objet décodé avec une liste ordonnée de paires. La valeur de retour object_pairs_hook sera utilisée à la place de dict. Cette fonctionnalité peut être utilisée pour implémenter des décodeurs personnalisés qui reposent sur l'ordre dans lequel les paires de clé et de valeur sont décodées (par exemple, collections.OrderedDict mémorisera l'ordre d'insertion). Si object_hook est également défini, le object_pairs_hook est prioritaire.

Avec cela, vous obtenez chaque objet JSON qui vous est remis, vous pouvez donc effectuer le décodage sans avoir besoin de récursivité:

def deunicodify_hook(pairs):
    new_pairs = []
    for key, value in pairs:
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        if isinstance(key, unicode):
            key = key.encode('utf-8')
        new_pairs.append((key, value))
    return dict(new_pairs)

In [52]: open('test.json').read()
Out[52]: '{"1": "hello", "abc": [1, 2, 3], "def": {"hi": "mom"}, "boo": [1, "hi", "moo", {"5": "some"}]}'                                        

In [53]: json.load(open('test.json'))
Out[53]: 
{u'1': u'hello',
 u'abc': [1, 2, 3],
 u'boo': [1, u'hi', u'moo', {u'5': u'some'}],
 u'def': {u'hi': u'mom'}}

In [54]: json.load(open('test.json'), object_pairs_hook=deunicodify_hook)
Out[54]: 
{'1': 'hello',
 'abc': [1, 2, 3],
 'boo': [1, 'hi', 'moo', {'5': 'some'}],
 'def': {'hi': 'mom'}}

Notez que je n'ai jamais à appeler le crochet de manière récursive car chaque objet sera remis au crochet lorsque vous utilisez le object_pairs_hook. Vous devez vous préoccuper des listes, mais comme vous pouvez le constater, un objet de la liste sera correctement converti et vous n'avez pas besoin de recurse pour le réaliser.

EDIT: Un collègue a fait remarquer que Python2.6 n’a pas object_hook_pairs. Vous pouvez toujours utiliser cette volonté Python2.6 en apportant une très petite modification. Dans le crochet ci-dessus, changez:

for key, value in pairs:

à

for key, value in pairs.iteritems():

Ensuite, utilisez object_hook au lieu de object_pairs_hook:

In [66]: json.load(open('test.json'), object_hook=deunicodify_hook)
Out[66]: 
{'1': 'hello',
 'abc': [1, 2, 3],
 'boo': [1, 'hi', 'moo', {'5': 'some'}],
 'def': {'hi': 'mom'}}

L'utilisation de object_pairs_hook entraîne l'instanciation d'un dictionnaire de moins pour chaque objet de l'objet JSON, ce qui, si vous analysez un document volumineux, peut valoir la peine.

10
Travis Jensen

Je crains qu'il n'y ait aucun moyen de réaliser cela automatiquement dans la bibliothèque simplejson.

Le scanner et le décodeur de simplejson sont conçus pour produire du texte unicode. Pour ce faire, la bibliothèque utilise une fonction appelée c_scanstring (si elle est disponible, pour plus de rapidité) ou py_scanstring si la version C n'est pas disponible. La fonction scanstring est appelée plusieurs fois par presque chaque routine de simplejson pour décoder une structure pouvant contenir du texte. Vous devez soit synchroniser la valeur scanstring dans simplejson.decoder, soit la sous-classe JSONDecoder et fournir à peu près votre propre implémentation de tout ce qui pourrait contenir du texte.

La raison pour laquelle simplejson génère unicode, cependant, est que la spécification json mentionne spécifiquement que "Une chaîne est une collection de zéro ou plusieurs caractères Unicode" ... la prise en charge de l'unicode est supposée faire partie du format lui-même. L'implémentation scanstring de Simplejson va jusqu'à analyser et interpréter les échappements unicode (même en vérifiant les erreurs pour les représentations de jeux de caractères multi-octets mal formées).

Si vous avez une vieille bibliothèque qui a besoin d'une str, je vous recommande de rechercher laborieusement la structure de données imbriquée après l'analyse (ce que je reconnais être ce que vous avez dit explicitement que vous vouliez éviter ... désolé), ou bien envelopper vos bibliothèques de façade où vous pouvez masser les paramètres d’entrée à un niveau plus granulaire. La deuxième approche pourrait être plus facile à gérer que la première si vos structures de données sont réellement imbriquées.

9
Jarret Hardie

Comme Mark (Amery) le remarque correctement: L’utilisation du désérialiseur de PyYaml sur un cliché Json ne fonctionne que si vous avez ASCII uniquement. Au moins hors de la boîte. 

Deux commentaires rapides sur l'approche PyYaml:

  1. NEVER utilise yaml.load sur les données du terrain. C'est une fonctionnalité (!) De yaml pour exécuter du code arbitraire caché dans la structure. 

  2. Vous pouvez faites le fonctionner aussi pour les non ASCII via ceci:

    def to_utf8(loader, node):
        return loader.construct_scalar(node).encode('utf-8')
    yaml.add_constructor(u'tag:yaml.org,2002:str', to_utf8)
    

Mais les performances sont sans comparaison avec la réponse de Mark Amery:

En jetant des exemples de dict profondément imbriqués sur les deux méthodes, je comprends ceci (avec dt [j] = delta temporel de json.loads (json.dumps (m))):

     dt[yaml.safe_load(json.dumps(m))] =~ 100 * dt[j]
     dt[byteify recursion(Mark Amery)] =~   5 * dt[j]

Donc, la désérialisation, y compris l’encodage complet de l’arborescence et, se situe bien dans l’ordre de grandeur de l’implémentation basée sur C de json. Je trouve cela remarquablement rapide et sa plus robuste que la charge yaml sur des structures profondément imbriquées. Et moins d'erreurs de sécurité, regardant yaml.load.

=> Bien que j'apprécie un pointeur sur un convertisseur basé uniquement sur C, la fonction byteify devrait être la réponse par défaut. 

Cela est particulièrement vrai si votre structure JSON provient du champ, contenant les entrées de l'utilisateur. Dans ce cas, vous devrez probablement passer de toute façon sur votre structure, indépendamment des structures de données internes souhaitées (chaînes 'sandwich unicode' ou chaînes d'octets uniquement).

Pourquoi?

Unicode normalisation. Pour les ignorants: Prenez un antidouleur et lisez ceci .

Donc, en utilisant la récursion byteify, vous faites d'une pierre deux coups: 

  1. obtenez vos bytestrings à partir de dumps json imbriqués
  2. obtenez des valeurs d'entrée utilisateur normalisées, de sorte que vous trouviez le contenu dans votre stockage.

Lors de mes tests, il s'est avéré que le remplacement du input.encode ('utf-8') par un unododata.normalize ('NFC', entrée) .encode ('utf-8') était encore plus rapide que w/o NFC - mais je suppose qu’il dépend fortement des données de l’échantillon.

4
Red Pill

La vérité est que simplejson et json sont deux modules différents, au moins de la manière dont ils traitent avec unicode. Vous avez json dans py 2.6+, ce qui vous donne des valeurs unicode, alors que simplejson renvoie des objets chaîne. Essayez simplement easy_install-ing simplejson dans votre environnement et voyez si cela fonctionne. Ça l'a fait pour moi.

3
ducu

Utilisez juste pickle au lieu de json pour dump et load, comme ceci:

    import json
    import pickle

    d = { 'field1': 'value1', 'field2': 2, }

    json.dump(d,open("testjson.txt","w"))

    print json.load(open("testjson.txt","r"))

    pickle.dump(d,open("testpickle.txt","w"))

    print pickle.load(open("testpickle.txt","r"))

La sortie qu'il produit est (les chaînes et les entiers sont gérés correctement):

    {u'field2': 2, u'field1': u'value1'}
    {'field2': 2, 'field1': 'value1'}
2
Stefan Gruenwald

Soutenez Python2 et 3 à l’aide de hook (from https://stackoverflow.com/a/33571117/558397 )

import requests
import six
from six import iteritems

requests.packages.urllib3.disable_warnings()  # @UndefinedVariable
r = requests.get("http://echo.jsontest.com/key/value/one/two/three", verify=False)

def _byteify(data):
    # if this is a unicode string, return its string representation
    if isinstance(data, six.string_types):
        return str(data.encode('utf-8').decode())

    # if this is a list of values, return list of byteified values
    if isinstance(data, list):
        return [ _byteify(item) for item in data ]

    # if this is a dictionary, return dictionary of byteified keys and values
    # but only if we haven't already byteified it
    if isinstance(data, dict):
        return {
            _byteify(key): _byteify(value) for key, value in iteritems(data)
        }
    # if it's anything else, return it in its original form
    return data

w = r.json(object_hook=_byteify)
print(w)

Résultats:

 {'three': '', 'key': 'value', 'one': 'two'}
1
abarik

Donc, j'ai rencontré le même problème. Devinez quel était le premier résultat de Google.

Parce que j'ai besoin de transmettre toutes les données à PyGTK, les chaînes unicode ne me sont pas non plus très utiles. J'ai donc une autre méthode de conversion récursive. C'est en fait également nécessaire pour la conversion JSON de typesafe - json.dump () s'arrêterait sur tous les non-littéraux, comme les objets Python. Ne convertit pas les index dict cependant.

# removes any objects, turns unicode back into str
def filter_data(obj):
        if type(obj) in (int, float, str, bool):
                return obj
        Elif type(obj) == unicode:
                return str(obj)
        Elif type(obj) in (list, Tuple, set):
                obj = list(obj)
                for i,v in enumerate(obj):
                        obj[i] = filter_data(v)
        Elif type(obj) == dict:
                for i,v in obj.iteritems():
                        obj[i] = filter_data(v)
        else:
                print "invalid object in data, converting to string"
                obj = str(obj) 
        return obj
1
mario

J'ai réécrit _parse_json () de Wells pour gérer les cas où l'objet json lui-même est un tableau (mon cas d'utilisation).

def _parseJSON(self, obj):
    if isinstance(obj, dict):
        newobj = {}
        for key, value in obj.iteritems():
            key = str(key)
            newobj[key] = self._parseJSON(value)
    Elif isinstance(obj, list):
        newobj = []
        for value in obj:
            newobj.append(self._parseJSON(value))
    Elif isinstance(obj, unicode):
        newobj = str(obj)
    else:
        newobj = obj
    return newobj
0
darnmarshall

C'est tard pour le jeu, mais j'ai construit ce lanceur de sorts récursif. Cela fonctionne pour mes besoins et je pense que c'est relativement complet. Cela peut vous aider.

def _parseJSON(self, obj):
    newobj = {}

    for key, value in obj.iteritems():
        key = str(key)

        if isinstance(value, dict):
            newobj[key] = self._parseJSON(value)
        Elif isinstance(value, list):
            if key not in newobj:
                newobj[key] = []
                for i in value:
                    newobj[key].append(self._parseJSON(i))
        Elif isinstance(value, unicode):
            val = str(value)
            if val.isdigit():
                val = int(val)
            else:
                try:
                    val = float(val)
                except ValueError:
                    val = str(val)
            newobj[key] = val

    return newobj

Passez juste un objet JSON comme ceci:

obj = json.loads(content, parse_float=float, parse_int=int)
obj = _parseJSON(obj)

Je l'ai en tant que membre privé d'une classe, mais vous pouvez réutiliser la méthode comme bon vous semble.

0
Wells

J'ai eu un dict JSON comme une chaîne. Les clés et les valeurs étaient des objets Unicode, comme dans l'exemple suivant:

myStringDict = "{u'key':u'value'}"

Je pourrais utiliser la fonction byteify suggérée ci-dessus en convertissant la chaîne en un objet dict à l'aide de ast.literal_eval(myStringDict).

0
narko

Découvrez ceci répondez à une question similaire comme celle-ci qui dit que

Le préfixe u signifie simplement que vous avez une chaîne Unicode. Lorsque vous utilisez réellement la chaîne, elle n'apparaît pas dans vos données. Ne soyez pas projeté par la sortie imprimée.

Par exemple, essayez ceci:

print mail_accounts[0]["i"]

Vous ne verrez pas un u.

0
kunal

Avec Python 3.6, je rencontre encore parfois ce problème. Par exemple, lorsque je reçois une réponse d'une API REST et que je charge le texte de la réponse au format JSON, je reçois toujours les chaînes unicode . Nous avons trouvé une solution simple à l'aide de json.dumps ().

response_message = json.loads(json.dumps(response.text))
print(response_message)
0
Yuelin

voici un encodeur récursif écrit en C: https://github.com/axiros/nested_encode

Surcharge de performances pour les structures "moyennes" d'environ 10% par rapport à json.loads.

python speed.py                                                                                            
  json loads            [0.16sec]: {u'a': [{u'b': [[1, 2, [u'\xd6ster..
  json loads + encoding [0.18sec]: {'a': [{'b': [[1, 2, ['\xc3\x96ster.
  time overhead in percent: 9%

en utilisant cette structure de test:

import json, nested_encode, time

s = """
{
  "firstName": "Jos\\u0301",
  "lastName": "Smith",
  "isAlive": true,
  "age": 25,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "\\u00d6sterreich",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
  ],
  "children": [],
  "spouse": null,
  "a": [{"b": [[1, 2, ["\\u00d6sterreich"]]]}]
}
"""


t1 = time.time()
for i in xrange(10000):
    u = json.loads(s)
dt_json = time.time() - t1

t1 = time.time()
for i in xrange(10000):
    b = nested_encode.encode_nested(json.loads(s))
dt_json_enc = time.time() - t1

print "json loads            [%.2fsec]: %s..." % (dt_json, str(u)[:20])
print "json loads + encoding [%.2fsec]: %s..." % (dt_json_enc, str(b)[:20])

print "time overhead in percent: %i%%"  % (100 * (dt_json_enc - dt_json)/dt_json)
0
Red Pill