अगर पायथन में एक स्ट्रिंग JSON मान्य है, तो मैं कैसे जांच करूं?


183

पायथन में, क्या यह जांचने का एक तरीका है कि क्या स्ट्रिंग को पार्स करने से पहले JSON वैध है?

उदाहरण के लिए, फेसबुक ग्राफ एपीआई जैसी चीजों के साथ काम करने पर, कभी-कभी यह JSON को लौटा देता है, कभी-कभी यह एक छवि फ़ाइल लौटा सकता है।


3
Api को सामग्री प्रकार सेट करना चाहिए
John La Rooy

4
आप यह नहीं बता सकते हैं कि API कॉल में कौन सा डेटा लौटाया गया है? मैं फेसबुक एपीआई से परिचित नहीं हूँ लेकिन यह बहुत अजीब लगता है।
झॉकिंग

मैं एक बार किया है, लेकिन साथ codegolf रास्ता
आप

1
अधिकांश प्रतिक्रियाएँ जस्सन हैं, लेकिन, यदि आप प्रोफ़ाइल फ़ोटो को कॉल करते हैं, तो यह सिर्फ jpg लौटाती है
जॉय ब्लेक

जवाबों:


233

आप करने की कोशिश कर सकते हैं json.loads(), जो ValueErrorकि यदि स्ट्रिंग आपके पास से गुजरती है तो JSON के रूप में डिकोड नहीं किया जा सकता है।

सामान्य तौर पर, इस तरह की स्थिति के लिए " पायथोनिक " दर्शन को ईएएफपी कहा जाता है , अनुमति के लिए आसान करने के लिए माफ़ी मांगना


4
मैं देख सकता हूं कि यह कैसे काम करेगा। मुझे मेरे अगले सवाल पर ले जाता है। यह एक ValueError फेंकता है। मैं इस बिंदु पर क्या करना चाहता हूं वह आपत्तिजनक स्ट्रिंग लौटा रहा है ताकि मैं इसके साथ कुछ और कर सकूं। अब तक, मैंने केवल त्रुटि संदेश और प्रकार प्राप्त किया है।
जॉय ब्लेक

2
loadsसिवाय क्लॉज में पास हुए स्ट्रिंग को वापस करने में क्या गलत है ?
जॉन फ्लैटनेस

1
इसके साथ कुछ भी गलत नहीं है, मेरी ओर से सिर्फ एक गलती। ऐसा लगता है कि मैं सिर्फ दो बार call.read () नहीं कर सकता। लेकिन मैं एक चर सेट कर सकता हूं और इसका उपयोग कर सकता हूं। और जो मैंने किया, वह किया।
जॉय ब्लेक

5
बस एक नोट ... json.loads ('10 ') ValueError को नहीं फेंकता है और मुझे यकीन है कि' 10 'एक वैध
जौन

4
इस तथ्य के बावजूद कि कल्पना कहती है कि एक JSON टेक्स्ट एक सरणी या ऑब्जेक्ट होना चाहिए, अधिकांश एन्कोडर और डिकोडर (पायथन सहित) नंबर और स्ट्रिंग्स सहित "टॉप" पर किसी भी JSON मान के साथ काम करेंगे। 10एक वैध JSON नंबर मान है।
जॉन फ्लैटनेस

144

उदाहरण पायथन स्क्रिप्ट एक बूलियन लौटाता है यदि एक स्ट्रिंग वैध जसन है:

import json

def is_json(myjson):
  try:
    json_object = json.loads(myjson)
  except ValueError as e:
    return False
  return True

कौन सा प्रिंट:

print is_json("{}")                          #prints True
print is_json("{asdf}")                      #prints False
print is_json('{ "age":100}')                #prints True
print is_json("{'age':100 }")                #prints False
print is_json("{\"age\":100 }")              #prints True
print is_json('{"age":100 }')                #prints True
print is_json('{"foo":[5,6.8],"foo":"bar"}') #prints True

एक JSON स्ट्रिंग को पायथन डिक्शनरी में बदलें:

import json
mydict = json.loads('{"foo":"bar"}')
print(mydict['foo'])    #prints bar

mylist = json.loads("[5,6,7]")
print(mylist)
[5, 6, 7]

एक अजगर वस्तु को JSON स्ट्रिंग में बदलें:

foo = {}
foo['gummy'] = 'bear'
print(json.dumps(foo))           #prints {"gummy": "bear"}

यदि आप निम्न-स्तरीय पार्सिंग तक पहुँच चाहते हैं, तो अपना रोल न करें, किसी मौजूदा लाइब्रेरी का उपयोग करें: http://www.json.org/

अजगर JSON मॉड्यूल पर महान ट्यूटोरियल: https://pymotw.com/2/json/

स्ट्रिंग JSON है और वाक्यविन्यास त्रुटियों और त्रुटि संदेश दिखाते हैं:

sudo cpan JSON::XS
echo '{"foo":[5,6.8],"foo":"bar" bar}' > myjson.json
json_xs -t none < myjson.json

प्रिंटों:

, or } expected while parsing object/hash, at character offset 28 (before "bar}
at /usr/local/bin/json_xs line 183, <STDIN> line 1.

json_xs वाक्यविन्यास जाँच, पार्सिंग, प्रिटिटाइजिंग, एन्कोडिंग, डिकोडिंग और बहुत कुछ करने में सक्षम है:

https://metacpan.org/pod/json_xs


क्या आपको लगता है कि हमें del json_objectएक बार मान्य होना चाहिए ?
अक्षय

4
क्यों नरक एक उचित सत्यापन विधि नहीं है? कैनरी को मारे बिना त्रुटि जांच का एक तरीका होना चाहिए।
ब्रैडेन बेस्ट

मुझे जो मिल रहा है वह है: सिर्फ इसलिए कि पायथन ओओ के लिए अनुमति देता है इसका मतलब यह नहीं है कि अन्य भागों को अनदेखा करना ठीक है। मेरे पास ए का विकल्प होना चाहिए, फ़ंक्शन को विफल होने देना और अपवादों का उपयोग करना (OO / पायथन तरीका), या B. एक फ़ंक्शन को कॉल करना जो अपवाद को फेंकने के बजाय एक मान (सफलता या त्रुटि) लौटाता है, और फिर मेरा फ़ंक्शन होता है बदले में, एक संतरी मान लौटाता है जो एक त्रुटि को इंगित करता है, ताकि त्रुटियों को कॉल स्टैक को बुलबुला कर दें और आवश्यक (प्रक्रियात्मक / सी तरीका) के रूप में उपयोग किया जा सके। जैसे ही C ++ आपको अपवादों का उपयोग करने के लिए मजबूर नहीं करता (आप इरनो का उपयोग कर सकते हैं), पायथन को इसे बाध्य नहीं करना चाहिए, या तो
ब्रैडेन बेस्ट

@BradenBest JSON स्ट्रिंग सत्यापन भूत द्वारा समस्या को रोचक बनाने वाले दानव द्वारा प्रेतवाधित है। एक स्ट्रिंग की शुद्धता साबित करने के लिए गणितीय रूप से कोई सही तरीका नहीं है सिवाय अपनी स्ट्रिंग को पार्सर के साथ आज़माने के लिए और देखें कि क्या यह बिना त्रुटियों के पूरा होता है। यह देखने के लिए कि यह कठिन क्यों है: "मुझे एक प्रोग्राम लिखें जो साबित करता है कि कंप्यूटर प्रोग्राम में कोई सिंटैक्स त्रुटियां मौजूद नहीं हैं"। यह संभव नहीं है। भाषा डेवलपर्स एन्कोडिंग और डिकोडिंग की शाश्वत हथियारों की दौड़ के बारे में काव्य को मोम करेंगे। सबसे अच्छा हम यह कर सकते हैं कि यदि कोई स्ट्रिंग किसी दिए गए इंजन के लिए वैध है / नहीं, तो सभी संभावित इंजनों के लिए नहीं।
एरिक लेसचिंस्की

1
@ EricLeschinski लेकिन यहाँ एक रुकने की समस्या नहीं है। यदि JSON को पार्स करते समय कोई त्रुटि होती है, तो प्रोग्राम स्पष्ट रूप से एक अपवाद उठाता है। इसलिए, प्रोग्राम जानता है कि JSON इनपुट कब अमान्य है। इसलिए, एक फ़ंक्शन का 100% संभव है जो यह जांचता है कि इनपुट का उपयोग किए बिना इनपुट वैध है या नहीं try। #StopCanaryAbuse
ब्रैडेन बेस्ट

2

मैं कहूंगा कि यह एकमात्र तरीका है जिसे आप वास्तव में पूरी तरह से बता सकते हैं। json.loads()यदि सही प्रारूप नहीं है तो अपवाद पायथन के कार्य द्वारा उठाया जाएगा (लगभग निश्चित रूप से)। हालांकि, आपके उदाहरण के उद्देश्य आप शायद गैर-व्हाट्सएप पात्रों के पहले जोड़े की जांच कर सकते हैं ...

मैं उस JSON से परिचित नहीं हूं जिसे facebook वापस भेजता है, लेकिन वेब ऐप्स से अधिकांश JSON तार एक खुले वर्ग [या घुंघराले {ब्रैकेट के साथ शुरू होगा । कोई चित्र प्रारूप नहीं जिन्हें मैं उन पात्रों के साथ शुरू करना जानता हूं।

इसके विपरीत यदि आप जानते हैं कि छवि प्रारूप क्या दिखा सकते हैं, तो आप छवियों को पहचानने के लिए उनके हस्ताक्षर के लिए स्ट्रिंग की शुरुआत की जांच कर सकते हैं, और मान लें कि आपके पास JSON है यदि यह छवि नहीं है।

एक ग्राफिक की पहचान करने के लिए एक और सरल हैक, एक टेक्स्ट स्ट्रिंग के बजाय, जिस मामले में आप एक ग्राफिक की तलाश कर रहे हैं, वह सिर्फ स्ट्रिंग के दर्जन भर पात्रों के पहले जोड़े में गैर-एएससीआईआईआई पात्रों के लिए परीक्षण करना है (यह मानते हुए कि JSON ASCII है )।


0

मैं इस समस्या का एक सामान्य, दिलचस्प समाधान लेकर आया हूं:

class SafeInvocator(object):
    def __init__(self, module):
        self._module = module

    def _safe(self, func):
        def inner(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                return None

        return inner

    def __getattr__(self, item):
        obj = getattr(self.module, item)
        return self._safe(obj) if hasattr(obj, '__call__') else obj

और आप इसे इस तरह से उपयोग कर सकते हैं:

safe_json = SafeInvocator(json)
text = "{'foo':'bar'}"
item = safe_json.loads(text)
if item:
    # do something

1
मुझे लगता है कि सामान्य समाधान अच्छे हैं, लेकिन इस मामले में, exceptखंड किसी भी गंभीर अपवाद को छिपा सकता है। कैचिंग अपवादों को यथासंभव प्रतिबंधात्मक होना चाहिए।
ल्यूकास्टामायोइस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.