TATECHATLAS
◎ हिन्दी
प्रोग्रामिंग

Python: JSON स्ट्रिंग्स और फ़ाइलों से पढ़ना, और डिकोडिंग त्रुटियों को संभालना

Python में अंतर्निहित `json` मॉड्यूल का उपयोग करके स्ट्रिंग लिटरल और फ़ाइलों दोनों से JSON डेटा को पार्स करना सीखें, और संभावित डिकोडिंग त्रुटियों को प्रभावी ढंग से कैसे संभालें।

इस पृष्ठ पर

Python का `json` मॉड्यूल स्ट्रिंग्स से JSON को पार्स करने के लिए `json.loads()` और फ़ाइल-जैसे ऑब्जेक्ट से पार्स करने के लिए `json.load()` प्रदान करता है। दोनों फ़ंक्शन `json.JSONDecodeError` बढ़ा सकते हैं यदि इनपुट मान्य JSON नहीं है, जिसे खराब डेटा को शालीनता से संभालने के लिए `try-except` ब्लॉक का उपयोग करके पकड़ा जा सकता है।

स्ट्रिंग से JSON पढ़ना

JSON स्ट्रिंग को Python ऑब्जेक्ट में डीसेरिएलाइज़ करने के लिए `json.loads()` फ़ंक्शन का उपयोग किया जाता है। यह इनपुट के रूप में एक स्ट्रिंग लेता है और संबंधित Python डेटा संरचना (जैसे, शब्दकोश, सूचियाँ, स्ट्रिंग्स, संख्याएँ, बूलियन, None) लौटाता है। यह तब उपयोगी होता है जब आपके Python कोड में सीधे JSON डेटा एम्बेड किया गया हो या API प्रतिक्रिया से स्ट्रिंग के रूप में प्राप्त हुआ हो।

उदाहरण के लिए, स्ट्रिंग के रूप में दर्शाए गए एक साधारण JSON ऑब्जेक्ट को पार्स करने के लिए, आप स्ट्रिंग को `json.loads()` में पास करेंगे।

import json

json_string = '{"name": "Alice", "age": 30, "isStudent": false}'

try:
    data = json.loads(json_string)
    print(data)
    print(f"Name: {data['name']}, Age: {data['age']}")
except json.JSONDecodeError as e:
    print(f"Error decoding JSON string: {e}")

फ़ाइल से JSON पढ़ना

जब आपका JSON डेटा किसी फ़ाइल में संग्रहीत होता है, तो आपको `json.load()` फ़ंक्शन का उपयोग करना चाहिए। यह फ़ंक्शन एक फ़ाइल-जैसे ऑब्जेक्ट (टेक्स्ट मोड में खुला) इनपुट के रूप में लेता है और उसमें से JSON डेटा पढ़ता है, इसे एक Python ऑब्जेक्ट में डीसेरिएलाइज़ करता है। फ़ाइल को सही ढंग से खोलना महत्वपूर्ण है, यह सुनिश्चित करते हुए कि इसे टेक्स्ट के रूप में पढ़ा गया है।

`with open(...)` स्टेटमेंट फ़ाइलों को संभालने का अनुशंसित तरीका है, क्योंकि यह सुनिश्चित करता है कि त्रुटियाँ होने पर भी फ़ाइल ठीक से बंद हो जाए। `json.load()` फ़ंक्शन तब फ़ाइल की सामग्री को संसाधित करता है।

import json

# मान लें कि 'data.json' में शामिल है: [{"id": 1, "value": "A"}, {"id": 2, "value": "B"}]
file_path = 'data.json'

try:
    with open(file_path, 'r', encoding='utf-8') as f:
        data = json.load(f)
        print(data)
except FileNotFoundError:
    print(f"Error: File not found at {file_path}")
except json.JSONDecodeError as e:
    print(f"Error decoding JSON from file: {e}")

JSON डिकोडिंग त्रुटियों को संभालना

JSON डेटा को एक सख्त प्रारूप का पालन करना चाहिए। यदि इनपुट स्ट्रिंग या फ़ाइल सामग्री मान्य JSON नहीं है, तो Python का `json` मॉड्यूल `json.JSONDecodeError` बढ़ाएगा। यह अपवाद पार्सिंग कहाँ विफल हुई, इसके बारे में विवरण प्रदान करता है, जैसे कि स्थिति और त्रुटि की प्रकृति।

इन त्रुटियों को शालीनता से संभालने के लिए, आपको अपने `json.loads()` या `json.load()` कॉलों को `try...except json.JSONDecodeError` ब्लॉक के भीतर लपेटना चाहिए। यह आपके प्रोग्राम को क्रैश होने के बजाय चलना जारी रखने या उपयोगकर्ता को जानकारीपूर्ण संदेश प्रदान करने की अनुमति देता है।

import json

malformed_json_string = '{"key": "value", "another_key": }' # Missing value

try:
    json.loads(malformed_json_string)
except json.JSONDecodeError as e:
    print(f"Caught a JSONDecodeError: {e}")
    print(f"Error occurred at line {e.lineno}, column {e.colno}")
    print(f"Error message: {e.msg}")

JSONDecodeError विवरण को समझना

The `json.JSONDecodeError` exception object में उपयोगी विशेषताएँ होती हैं जो आपके JSON डेटा में सटीक समस्या को इंगित करने में मदद कर सकती हैं। इनमें `msg` (त्रुटि संदेश), `doc` (पार्स किया जा रहा इनपुट स्ट्रिंग), `pos` (दस्तावेज़ में वर्ण सूचकांक जहाँ त्रुटि हुई), `lineno` (लाइन नंबर), और `colno` (कॉलम नंबर) शामिल हैं।

इन विशेषताओं का निरीक्षण करके, आप खराब JSON के बारे में अधिक विशिष्ट प्रतिक्रिया प्रदान कर सकते हैं, जो डिबगिंग में सहायता करता है या डेटा गुणवत्ता समस्या के बारे में उपयोगकर्ता को सूचित करता है।

import json

json_string_with_error = '''
{
    "name": "Bob",
    "details": {
        "city": "New York",
        "zip": 10001 # Missing comma here
        "country": "USA"
    }
}
'''

try:
    json.loads(json_string_with_error)
except json.JSONDecodeError as e:
    print(f"Error: {e.msg}")
    print(f"Document: {e.doc[max(0, e.pos-10):e.pos+10]}...") # Show context
    print(f"Position: {e.pos}, Line: {e.lineno}, Column: {e.colno}")

JSON डिकोडिंग को अनुकूलित करना

The `json.load()` और `json.loads()` फ़ंक्शन JSON डेटा को कैसे डीकोड किया जाता है, इसे अनुकूलित करने के लिए `object_hook`, `parse_float`, `parse_int`, और `parse_constant` जैसे पैरामीटर प्रदान करते हैं। उदाहरण के लिए, `parse_float` का उपयोग फ्लोटिंग-पॉइंट नंबरों को मानक फ्लोट के बजाय `Decimal` ऑब्जेक्ट में डीसेरिएलाइज़ करने के लिए किया जा सकता है, जो सटीक दशमलव अंकगणित की आवश्यकता वाले वित्तीय अनुप्रयोगों के लिए उपयोगी है।

इसी तरह, `object_hook` डीकोड किए गए JSON ऑब्जेक्ट (Python शब्दकोश) को कस्टम क्लास इंस्टेंस में बदल सकता है, जिससे अधिक ऑब्जेक्ट-ओरिएंटेड डेटा हैंडलिंग सक्षम होती है।

import json
import decimal

json_string_with_floats = '{"price": "19.99", "tax": "1.50"}'

# सटीक फ्लोट पार्सिंग के लिए Decimal का उपयोग करें
data = json.loads(json_string_with_floats, parse_float=decimal.Decimal)

print(f"Parsed data: {data}")
print(f"Type of price: {type(data['price'])}")

# ऑब्जेक्ट बनाने के लिए object_hook के साथ उदाहरण
def dict_to_person(d):
    if '__class__' in d and d['__class__'] == 'Person':
        return Person(d['name'], d['age'])
    return d

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __repr__(self):
        return f"Person(name='{self.name}', age={self.age})"

json_person = '{"__class__": "Person", "name": "Charlie", "age": 25}'
person_obj = json.loads(json_person, object_hook=dict_to_person)
print(f"Decoded object: {person_obj}")

Python ऑब्जेक्ट्स को JSON में एन्कोड करना

जबकि ध्यान JSON पढ़ने पर है, विपरीत ऑपरेशन को नोट करना उचित है: क्रमशः `json.dumps()` और `json.dump()` का उपयोग करके Python ऑब्जेक्ट्स को JSON स्ट्रिंग्स या फ़ाइलों में एन्कोड करना। ये फ़ंक्शन Python डेटा प्रकारों को उनके JSON समकक्षों में रूपांतरण को संभालते हैं।

वे अनुकूलन का भी समर्थन करते हैं, जैसे कि गैर-सीरियलाइज़ेबल प्रकारों को संभालने के लिए `default`, प्रीटी-प्रिंटिंग के लिए `indent`, और क्रमबद्ध आउटपुट के लिए `sort_keys`, जो डिबगिंग और पठनीयता के लिए बहुत मददगार हो सकता है।

import json

python_data = {
    "name": "David",
    "scores": [95, 88, 76],
    "isActive": True,
    "metadata": None
}

# प्रीटी-प्रिंटिंग के साथ JSON स्ट्रिंग में एन्कोड करें
json_output_string = json.dumps(python_data, indent=4, sort_keys=True)
print("--- JSON String Output ---")
print(json_output_string)

# फ़ाइल में एन्कोड करें (प्रदर्शन के लिए StringIO का उपयोग करके उदाहरण)
from io import StringIO
output_file = StringIO()
json.dump(python_data, output_file, indent=4)
output_file.seek(0) # सामग्री पढ़ने के लिए वापस जाएं
print("\n--- JSON File Output (simulated) ---")
print(output_file.read())

सुरक्षा संबंधी विचार

अविश्वसनीय स्रोतों से JSON डेटा को पार्स करने के लिए सावधानी की आवश्यकता होती है। दुर्भावनापूर्ण रूप से तैयार किए गए JSON को अत्यधिक CPU और मेमोरी संसाधनों की खपत करने के लिए डिज़ाइन किया जा सकता है, जिससे संभावित रूप से सेवा से इनकार (denial-of-service) के हमले हो सकते हैं। `json` मॉड्यूल में `check_circular` (डिफ़ॉल्ट रूप से सक्षम) जैसे चेक शामिल हैं ताकि सर्कुलर संदर्भों के साथ अनंत पुनरावृत्ति को रोका जा सके।

बाहरी या अविश्वसनीय इनपुट के साथ काम करते समय पार्स किए जा रहे डेटा के आकार को सीमित करने की अनुशंसा की जाती है। बहुत बड़ी JSON फ़ाइलों के लिए, स्ट्रीमिंग JSON पार्सर पर विचार करें या यदि संभव हो तो डेटा को टुकड़ों में संसाधित करें, हालांकि Python का मानक `json` मॉड्यूल मुख्य रूप से पूरे दस्तावेज़ के साथ एक बार में काम करता है।

import json

# संभावित रूप से संसाधन-गहन JSON संरचना का उदाहरण (सरलीकृत)
# एक वास्तव में दुर्भावनापूर्ण स्ट्रिंग बहुत अधिक जटिल होगी।
# json मॉड्यूल में कुछ अंतर्निहित सुरक्षा उपाय हैं, लेकिन बड़े इनपुट अभी भी जोखिम हैं।

# सर्कुलर संदर्भ का उदाहरण (यदि check_circular True है तो RecursionError बढ़ाएगा)
# data = {}
# data['self'] = data
# try:
#     json.dumps(data, check_circular=True)
# except RecursionError as e:
#     print(f"Caught expected error for circular reference: {e}")

# इनपुट आकार को सीमित करना एक व्यावहारिक सुरक्षा उपाय है
max_size = 1024 * 1024 # 1 MB

json_input = '{"key": "value"}' # वास्तविक इनपुट स्रोत से बदलें

if len(json_input.encode('utf-8')) > max_size:
    print("Error: Input JSON data exceeds maximum allowed size.")
else:
    try:
        data = json.loads(json_input)
        print("JSON parsed successfully within size limits.")
    except json.JSONDecodeError as e:
        print(f"Error decoding JSON: {e}")

`pathlib` का उपयोग फ़ाइल पथों के लिए

JSON फ़ाइलों के साथ काम करते समय, फ़ाइल पथों का प्रबंधन अक्सर आवश्यक होता है। Python का `pathlib` मॉड्यूल फ़ाइल सिस्टम पथों के लिए एक ऑब्जेक्ट-ओरिएंटेड दृष्टिकोण प्रदान करता है, जिससे यह `os.path` के साथ स्ट्रिंग हेरफेर की तुलना में क्लीनर और अधिक मजबूत हो जाता है।

आप `Path` ऑब्जेक्ट बना सकते हैं और उन्हें सीधे `open()` और `json.load()` के साथ उपयोग कर सकते हैं। यह फ़ाइल हैंडलिंग और JSON पार्सिंग को सहजता से एकीकृत करता है। `pathlib` विभिन्न ऑपरेटिंग सिस्टमों में सही ढंग से पथ सेपरेटरों को संभालता है।

import json
from pathlib import Path

# pathlib का उपयोग करके JSON फ़ाइल का पथ परिभाषित करें
file_path = Path('config.json')

# सुनिश्चित करें कि फ़ाइल मौजूद है और इसमें मान्य JSON है, उदा.:
# {"database": "localhost", "port": 5432}

try:
    # open() के साथ सीधे Path ऑब्जेक्ट का उपयोग करें
    with file_path.open('r', encoding='utf-8') as f:
        config_data = json.load(f)
        print(f"Configuration loaded: {config_data}")
        print(f"Database host: {config_data.get('database')}")
except FileNotFoundError:
    print(f"Error: Configuration file not found at {file_path}")
except json.JSONDecodeError as e:
    print(f"Error decoding JSON from {file_path}: {e}")
except Exception as e:
    print(f"An unexpected error occurred: {e}")

क्या जाँचें

  • सत्यापित करें कि JSON स्ट्रिंग या फ़ाइल सामग्री JSON विनिर्देशों के अनुसार सही ढंग से स्वरूपित है (जैसे, डबल कोट्स में कुंजियाँ और स्ट्रिंग्स, अल्पविराम, ब्रेसिज़ और कोष्ठकों का सही उपयोग)।
  • सुनिश्चित करें कि `json.load()` के साथ उपयोग किए जाने वाले फ़ाइल पथ सही हैं और फ़ाइल में उचित पढ़ने की अनुमतियाँ हैं।
  • त्रुटिपूर्ण JSON को शालीनता से संभालने के लिए `json.JSONDecodeError` को पकड़ने के लिए `json.loads()` और `json.load()` के आसपास `try-except` ब्लॉक लागू करें।
  • संभावित एन्कोडिंग मुद्दों से बचने के लिए JSON पढ़ने के लिए फ़ाइलें खोलते समय `encoding='utf-8'` का उपयोग करने पर विचार करें।
  • अविश्वसनीय डेटा के लिए, सेवा से इनकार के जोखिमों को कम करने के लिए इनपुट JSON पर आकार सीमा लागू करें।

`json` मॉड्यूल JSON को मानक Python प्रकारों में डीकोड करता है। जटिल कस्टम प्रकारों या विशिष्ट संख्यात्मक परिशुद्धता (जैसे वित्तीय गणना) के लिए, आपको कस्टम फ़ंक्शन (जैसे, `decimal.Decimal`) के साथ `object_hook` या `parse_float` का उपयोग करने की आवश्यकता हो सकती है। मॉड्यूल पूरे JSON दस्तावेज़ को मेमोरी में पार्स करता है, जो अत्यंत बड़ी फ़ाइलों के लिए एक समस्या हो सकती है; ऐसे मामलों में वैकल्पिक स्ट्रीमिंग JSON पार्सर की आवश्यकता हो सकती है। अविश्वसनीय स्रोतों के संबंध में सुरक्षा चेतावनियाँ महत्वपूर्ण हैं; जहाँ संभव हो हमेशा इनपुट को मान्य या साफ़ करें।

स्रोत

  1. Python: json ↗
  2. Python: pathlib ↗
ऊपर जाएँ ↑