Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting identifier naming between camelCase and underscores during JSON serialization/deserialization

Tags:

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.

like image 511
tamakisquare Avatar asked Jun 17 '13 20:06

tamakisquare


1 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.

like image 63
Jared Avatar answered Sep 25 '22 10:09

Jared