Answer a question

I am working on a python/django application that serves as a web API server to its frontend counterpart. The data exchange between the server and the client is in JSON format with the use of XMLHttpRequest (Javascript). For those that are familiar with both Python and Javascript, you know that they have different identifier naming convention when it comes to variables/methods/attributes; Python uses names_with_underscores while Javascript prefers camelCaseNames. I would like to keep both conventions in their respective worlds and perform conversion on identifiers when data exchange happens.

I have decided to have the conversion performed on the server (Python). In my own opinion, the most logical place for this two-way conversion to happen is during JSON serialization/deserialization. How should I go about implementing this approach? Examples are highly appreciated.

Note that I am on Python 2.7.

Answers

One way to do it using regular expressions,

import re

camel_pat = re.compile(r'([A-Z])')
under_pat = re.compile(r'_([a-z])')

def camel_to_underscore(name):
    return camel_pat.sub(lambda x: '_' + x.group(1).lower(), name)

def underscore_to_camel(name):
    return under_pat.sub(lambda x: x.group(1).upper(), name)

And,

>>> camel_to_underscore('camelCaseNames')
'camel_case_names'
>>> underscore_to_camel('names_with_underscores')
'namesWithUnderscores'

Note: You have to use a function (lambda expression here) for accomplishing the case change but that seems pretty straightforward.

EDIT:

If you truly wanted to intercept and adjust json objects between Python and Javascript you would have to rewrite functionality of the json module. But I think that is much more trouble than it's worth. Instead something like this would be equivalent and not be too much of a hit performance-wise.

To convert each key in a dict representing your json object, you can do something like this,

def convert_json(d, convert):
    new_d = {}
    for k, v in d.iteritems():
        new_d[convert(k)] = convert_json(v,convert) if isinstance(v,dict) else v
    return new_d

You only need to provide which function to apply,

>>> json_obj = {'nomNom': {'fooNom': 2, 'camelFoo': 3}, 'camelCase': {'caseFoo': 4, 'barBar': {'fooFoo': 44}}}
>>> convert_json(json_obj, camel_to_underscore)
{'nom_nom': {'foo_nom': 2, 'camel_foo': 3}, 'camel_case': {'case_foo': 4, 'bar_bar': {'foo_foo': 44}}}

You can wrap all of this logic in new load and dump functions,

import json

def convert_load(*args, **kwargs):
    json_obj = json.load(*args, **kwargs)
    return convert_json(json_obj, camel_to_underscore)

def convert_dump(*args, **kwargs):
    args = (convert_json(args[0], underscore_to_camel),) + args[1:]
    json.dump(*args, **kwargs)

And use then just as you would json.load and json.dump.

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐