2013-06-17 8 views
7

मैं एक अजगर/Django अनुप्रयोग है कि अपने दृश्यपटल समकक्ष के लिए एक वेब API सर्वर रूप में कार्य करता पर काम कर रहा हूँ के दौरान रेखांकित। सर्वर और क्लाइंट के बीच डेटा एक्सचेंज JSH प्रारूप में XMLHttpRequest (जावास्क्रिप्ट) के उपयोग के साथ है। उन लोगों के लिए जो पाइथन और जावास्क्रिप्ट दोनों से परिचित हैं, आप जानते हैं कि चर/विधियों/विशेषताओं की बात करते समय उनके पास अलग-अलग पहचानकर्ता नामकरण सम्मेलन है; पायथन names_with_underscores का उपयोग करता है जबकि जावास्क्रिप्ट camelCaseNames पसंद करता है। मैं डेटा सम्मेलन होने पर दोनों सम्मेलनों को अपने संबंधित दुनिया में रखना और पहचानकर्ताओं पर रूपांतरण करना चाहता हूं।परिवर्तित पहचानकर्ता CamelCase के बीच नामकरण और JSON क्रमबद्धता/अक्रमांकन

मैं रूपांतरण सर्वर (अजगर) पर प्रदर्शन करने का निर्णय लिया है। मेरी राय में, इस दो-तरफा रूपांतरण के लिए सबसे तार्किक स्थान जेएसओएन क्रमबद्धता/deserialization के दौरान होता है। इस दृष्टिकोण को लागू करने के लिए मुझे कैसे जाना चाहिए? उदाहरणों की अत्यधिक सराहना की जाती है।

ध्यान दें कि मैं अजगर 2.7 पर हूँ। नियमित अभिव्यक्ति का उपयोग कर यह करने के लिए

उत्तर

11

एक तरह से,

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) 

और,

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

नोट: आप मामले परिवर्तन पूरा करने के लिए एक समारोह (यहाँ lambda अभिव्यक्ति) का उपयोग करने के लिए है, लेकिन यह बहुत सरल लगता है।

संपादित करें:

आप वास्तव में रोकना और अजगर और जावास्क्रिप्ट के बीच json वस्तुओं आप json मॉड्यूल की कार्यक्षमता को फिर से लिखने करना होगा समायोजित करना चाहता है तो। लेकिन मुझे लगता है कि यह इसके लायक से ज्यादा परेशानी है। इसके बजाए ऐसा कुछ समकक्ष होगा और हिट प्रदर्शन-वार के बहुत अधिक नहीं होगा।

अपने json वस्तु को दिखाने वाला dict में प्रत्येक कुंजी बदलने के लिए, आप कुछ इस तरह कर सकते हैं,

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 

आप केवल प्रदान करने के लिए जो लागू करने के लिए कार्य करते हैं की जरूरत है,

>>> 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}}} 

आप लपेट कर सकते हैं इस तर्क के नए 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) 

और तब उपयोग करें जैसे आप json.load और json.dump करेंगे।

+0

+1 अच्छा एक है, बहुत अच्छा विचार! –

+0

@ जेरेड - यह रूपांतरण के लिए एक अच्छा समाधान है। लेकिन क्या आप जानते हैं कि मैं आपके प्रदान किए गए कोड के साथ JSON serialization/deserialization (मैं पायथन के 'जेसन' मॉड्यूल का उपयोग कर रहा हूं) को कैसे रोक सकता हूं? – tamakisquare

+0

@tamakisquare तो आप बस जानना चाहते हैं कि प्रत्येक जेसन कुंजी पर कैसे पुनरावृत्ति करें और परिवर्तित करें? – Jared

9

जारेड का जवाब एक 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 

उपयोग::

json वस्तु के भीतर 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 

लिए

def convert(s): 
    a = re.compile('((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))') 
    return a.sub(r'_\1', s).lower() 

सरणियों के लिए:

underscores_with_spaces को केमलकेस से परिवर्तित करने के लिए

पैदावार:

{ 
    'some_object': [ 
     { 
      'another_object': 'CamelCaseValue' 
     }, 
     { 
      'another_object': 'AnotherCamelCaseValue' 
     } 
    ] 
} 
संबंधित मुद्दे