我正在开发一个python/django应用程序,作为其前端对应的Web API服务器.服务器和客户端之间的数据交换采用JSON格式,使用XMLHttpRequest(Javascript).对于那些熟悉Python和Javascript的人,你知道他们在变量/方法/属性方面有不同的标识符命名约定; Python使用,names_with_underscores
而Javascript更喜欢camelCaseNames
.我想在各自的世界中保留这两个约定,并在数据交换发生时执行标识符的转换.
我决定在服务器上执行转换(Python).在我看来,这种双向转换最合乎逻辑的地方是在JSON序列化/反序列化期间.我该如何实施这种方法?例子受到高度赞赏.
请注意,我使用的是Python 2.7.
Jar*_*red 18
使用正则表达式的一种方法,
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)
Run Code Online (Sandbox Code Playgroud)
和,
>>> camel_to_underscore('camelCaseNames')
'camel_case_names'
>>> underscore_to_camel('names_with_underscores')
'namesWithUnderscores'
Run Code Online (Sandbox Code Playgroud)
注意:您必须使用函数(lambda
此处为表达式)来完成大小写更改,但这看起来非常简单.
编辑:
如果你真的想在Python和Javascript之间拦截和调整json对象,你将不得不重写json模块的功能.但我认为这比它的价值更麻烦.相反,像这样的东西是等价的,而不是太明显的性能.
要转换dict
代表你的json对象的每个键,你可以做这样的事情,
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
Run Code Online (Sandbox Code Playgroud)
您只需提供要应用的功能,
>>> 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}}}
Run Code Online (Sandbox Code Playgroud)
你可以将所有这些逻辑包装在新的load
和dump
函数中,
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)
Run Code Online (Sandbox Code Playgroud)
然后使用就像你json.load
和json.dump
.
Eva*_*oky 12
Jared的回答没有考虑json对象结构中带有对象的数组的可能性.
该解决方案需要三个函数来递归处理数组.
从CamelCase转换为underscores_with_spaces:
def convert(s):
a = re.compile('((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))')
return a.sub(r'_\1', s).lower()
Run Code Online (Sandbox Code Playgroud)
对于json对象
def convertJSON(j):
out = {}
for k in j:
newK = convert(k)
if isinstance(j[k],dict):
out[newK] = convertJSON(j[k])
elif isinstance(j[k],list):
out[newK] = convertArray(j[k])
else:
out[newK] = j[k]
return out
Run Code Online (Sandbox Code Playgroud)
对于json对象中的数组:
def convertArray(a):
newArr = []
for i in a:
if isinstance(i,list):
newArr.append(convertArray(i))
elif isinstance(i, dict):
newArr.append(convertJSON(i))
else:
newArr.append(i)
return newArr
Run Code Online (Sandbox Code Playgroud)
用法:
convertJSON({
"someObject": [
{
"anotherObject": "CamelCaseValue"
},
{
"anotherObject": "AnotherCamelCaseValue"
}
]
})
Run Code Online (Sandbox Code Playgroud)
产量:
{
'some_object': [
{
'another_object': 'CamelCaseValue'
},
{
'another_object': 'AnotherCamelCaseValue'
}
]
}
Run Code Online (Sandbox Code Playgroud)
对于未来的 googlers,该humps
软件包可以为您完成此操作。
import humps
humps.decamelize({'outerKey': {'innerKey': 'value'}})
# {'outer_key': {'inner_key': 'value'}}
Run Code Online (Sandbox Code Playgroud)