Skip to content
This page has been auto-translated and may contain errors.View in English

फ़ाइलें और अपवाद

docs.scrimba.com

ज्यादातर प्रोग्राम जो असली काम करते हैं वह फ़ाइल सिस्टम को छूते हैं: कॉन्फ़िग पढ़ना, परिणाम लिखना, डेटा लोड करना। और जब चीजें गलत हो जाती हैं, तो पायथन एक अपवाद उठाता है, एक संकेत कि कुछ अप्रत्याशित हुआ। यह अध्याय दोनों को कवर करता है: फ़ाइलों में और बाहर डेटा प्राप्त करना, और ऐसा कोड लिखना जो त्रुटियों को सुंदरता से संभालता है, क्रैश होने के बजाय।

फ़ाइल I/O और अपवाद हैंडलिंग दोनों ही तंत्र हैं जो एक प्रोग्राम को विश्वसनीय बनाते हैं। open() फ़ाइल सिस्टम तक पहुंच देता है; with यह सुनिश्चित करता है कि फ़ाइल को त्रुटि होने पर भी साफ किया जाए। try/except विशिष्ट अपवाद प्रकारों को पकड़ता है ताकि आप क्रैश होने के बजाय ठीक हो सकें। एक साथ वे किसी भी स्क्रिप्ट की नींव हैं जो निरीक्षण के बिना चलती है।

फ़ाइलें और अपवाद वह जगह हैं जहां एक स्क्रिप्ट बाहरी दुनिया को छूती है: एक पथ जो मौजूद नहीं है, एक डिस्क जो भर जाती है, इनपुट जो पार्स नहीं होता। open() एक फ़ाइल ऑब्जेक्ट वापस करता है, और with यह गारंटी देता है कि यह तब भी बंद हो जाए जब अंदर का कोड एक अपवाद उठाए। अपवाद यह है कि पायथन विफलता को कैसे संकेत देता है: जब एक उठाया जाता है, तो यह उन कॉल के माध्यम से ऊपर की ओर यात्रा करता है जो इसके कारण हैं, और पहला मिलान करने वाला except इसे संभालता है। इस अध्याय की अनुशासन यह है कि विशिष्ट विफलताओं को पकड़ना जिनसे आप वास्तव में ठीक हो सकते हैं और बाकी को जोर से सामने आने दें, सब कुछ निगलने के बजाय और एक स्क्रिप्ट भेजें जो चुप्पी में विफल होती है।

फ़ाइलें खोलना

open() एक फ़ाइल खोलता है और एक ऑब्जेक्ट वापस करता है जिससे आप पढ़ या लिख सकते हैं। आप इसे पथ बताते हैं और आप फ़ाइल के साथ क्या करना चाहते हैं (पढ़ें, लिखें, या जोड़ें)। जब आप हो जाएं तो हमेशा एक फ़ाइल बंद करें; with कथन यह स्वचालित रूप से करता है।

open(path, mode) एक फ़ाइल ऑब्जेक्ट वापस करता है। मोड स्ट्रिंग एक्सेस को नियंत्रित करती है: "r" पढ़ता है, "w" लिखता है (पहले फ़ाइल को साफ करता है), "a" अंत में जोड़ता है। फ़ाइल पाठ न होने पर बाइनरी मोड के लिए "b" जोड़ें। एक चीज शुरुआत से ही सेट करने के लायक है: पाठ फ़ाइलों के लिए encoding="utf-8" पास करें। इसे छोड़ दें और पायथन जो भी मशीन का डिफ़ॉल्ट है उसका उपयोग करता है, इसलिए एक फ़ाइल जो आपके लैपटॉप पर अच्छी तरह से पढ़ी जाती है, किसी और के कंप्यूटर पर टूटे हुए वर्णों के साथ वापस आ सकती है।

open() OS से फ़ाइल पर एक हैंडल मांगता है और इसके चारों ओर एक फ़ाइल ऑब्जेक्ट लपेटता है। मोड एक्सेस ("r", "w", "a") और पाठ बनाम कच्चे बाइट ("b") दोनों को चुनता है। जो पैरामीटर लोगों को काटता है वह encoding है: यह तय करता है कि डिस्क पर बाइट्स कैसे वर्णों में मैप होते हैं। इसे बिना सेट किए छोड़ दें और पायथन मशीन के लोकेल डिफ़ॉल्ट को वापस लेता है, जो प्लेटफ़ॉर्म के बीच अलग है, इसलिए एक मशीन पर लिखी गई फ़ाइल दूसरी पर गलत तरीके से डीकोड हो सकती है। हमेशा पाठ के लिए encoding="utf-8" पास करें जब तक आपके पास एक विशिष्ट कारण न हो, और आश्चर्य ज्यादातर गायब हो जाते हैं।

python
f = open("data.txt", "r")    # "r" = पढ़ें
content = f.read()
f.close()

"r" मोड है:

मोडअर्थ
"r"पढ़ें। फ़ाइल मौजूद होनी चाहिए। डिफ़ॉल्ट मोड।
"w"लिखें। फ़ाइल को बनाता या ओवरराइट करता है।
"a"जोड़ें। बिना मिटाए अंत में जोड़ता है।
"x"बनाएँ। फ़ाइल पहले से मौजूद होने पर विफल हो जाता है।
"r+"पढ़ें और लिखें।
"b"बाइनरी। किसी भी मोड में जोड़ें: "rb", "wb"

जब आप हो जाएं तो हमेशा .close() को कॉल करें। इसे भूलने से फ़ाइल खुली रह जाती है और डेटा खो सकता है जो अभी भी लिखे जाने की प्रतीक्षा में है। इसे संभालने का विश्वसनीय तरीका with कथन है।

Junoफ़ाइलें खोलनाopen(path, mode) आपको एक फ़ाइल ऑब्जेक्ट देता है, और मोड कहता है कि आप क्या करना चाहते हैं: पढ़ने के लिए "r", लिखने के लिए "w" (जो वहाँ जो कुछ है उसे मिटा देता है), अंत में जोड़ने के लिए "a"। मैंने एक बार एक फ़ाइल खो दी थी "w" से तब जब मेरा मतलब "a" था, तो मोड को टाइप करने से पहले कल्पना करें।
Junoफ़ाइलें खोलनाopen(path, mode) एक फ़ाइल ऑब्जेक्ट वापस करता है: "r" पढ़ें, "w" ओवरराइट करें, "a" जोड़ें, साथ ही बाइनरी के लिए "b"। पाठ फ़ाइलों पर encoding="utf-8" पास करें ताकि वे हर मशीन पर समान पढ़े जाएँ, और with को बंद करने का काम संभालने दें।
Junoफ़ाइलें खोलनाopen() आपको एक OS हैंडल पर एक फ़ाइल ऑब्जेक्ट देता है; मोड पाठ-बनाम-बाइट एक्सेस सेट करता है। जो सेटिंग खराब तरीके से यात्रा करती है वह है `encoding`: इसे छोड़ दें और आप मशीन के लोकेल डिफ़ॉल्ट को विरासत में लेते हैं, इसलिए पाठ के लिए `encoding="utf-8"` आदत बनाएँ। जब `with` करेगा तो हाथ से `.close()` पर निर्भर न रहें।

with कथन

with open(...) फ़ाइल का प्रबंधन आपके लिए करता है, इंडेंटेड ब्लॉक समाप्त होने पर इसे स्वचालित रूप से बंद करता है, भले ही एक त्रुटि हो। हमेशा with open(...) का उपयोग करें मैनुअल open()/close() के बजाय। यह सुरक्षित है और यह मानक है।

with पायथन का संदर्भ प्रबंधक वाक्यविन्यास है: एक छोटा प्रोटोकॉल जहां एक ऑब्जेक्ट को ब्लॉक शुरू होने पर एक "सेट अप" कॉल और अंत में एक "टियर डाउन" कॉल मिलता है। एक फ़ाइल के लिए, सेट-अप खुली फ़ाइल लौटाता है और टियर-डाउन इसे बंद करता है। लाभ यह है कि ब्लॉक के अंदर एक अपवाद उठाया जाने पर भी टियर-डाउन चलता है, इसलिए आप हर फ़ाइल के चारों ओर एक try/finally लिखे बिना सफाई प्राप्त करते हैं।

एक संदर्भ प्रबंधक (कोई भी ऑब्जेक्ट जो आप with के बाद लगा सकते हैं) दो व्यवहार परिभाषित करता है: अंदर की ओर क्या करना है, और बाहर की ओर क्या करना है। with open(...) as f अंदर-की-ओर कदम चलाता है, फ़ाइल को f से बाँधता है, और बाहर-की-ओर कदम को पंजीकृत करता है, जो पायथन तब चलाता है जब ब्लॉक समाप्त होता है, चाहे वह सामान्य रूप से समाप्त हुआ हो या क्योंकि एक अपवाद उठाया गया था। फ़ाइलों के लिए बाहर-की-ओर कदम close() है। दो व्यावहारिक नोट्स। आप एक कथन में कई फ़ाइलें खोल सकते हैं, with open(a) as f, open(b) as g:, और दोनों क्रम में बंद हो जाते हैं। और बाहर-की-ओर कदम अपवाद को निगलना चुन सकता है, जो यह है कि contextlib.suppress(FileNotFoundError) जैसे सहायकों को कैसे काम करता है, इसलिए जानें कि एक with ब्लॉक शांति से एक त्रुटि को अवशोषित कर सकता है यदि संदर्भ प्रबंधक इसके लिए लिखा गया था।

python
with open("data.txt", "r") as f:
    content = f.read()

# f यहाँ बंद है, गारंटीशुदा

with पायथन का संदर्भ प्रबंधक वाक्यविन्यास है: यह आपके लिए सेटअप और टियरडाउन कोड चलाता है, यहाँ फ़ाइल को खोलता है और विश्वसनीय रूप से इसे बंद करता है। इसे आंतरिक रूप से कैसे काम करता है यह जानने की आवश्यकता नहीं है इसे open() के साथ उपयोग करने के लिए।

Junowith कथनwith open(...) as f फ़ाइल को खोलता है, आपको इंडेंटेड ब्लॉक के अंदर f के साथ काम करने देता है, फिर ब्लॉक समाप्त होने पर इसे बंद करता है, भले ही कुछ गलत हो जाए। इसके बजाय स्वयं `.close()` को कॉल करना हर बार बेहतर है, यह भूलने के लिए एक कम चीज है।
Junowith कथन `with` ब्लॉक खुलने पर सेटअप चलाता है और बंद होने पर सफाई करता है, और अपवाद पर भी सफाई चलती है। एक फ़ाइल के लिए वह सफाई `close()` है, इसलिए आप `try`/`finally` सुरक्षा प्राप्त करते हैं बिना एक लिखे। हर बार मैनुअल `open()`/`close()` के ऊपर इसे पसंद करें।
Junowith कथन एक संदर्भ प्रबंधक फ़ाइल को बाहर की ओर बंद करता है चाहे ब्लॉक समाप्त हो या उठाया गया हो, तो `with` हाथ से लिखे गए `try`/`finally` को सफाई के लिए प्रतिस्थापित करता है। एक `with` के साथ कई एक बार खोलें। ध्यान रखें कि बाहर-की-ओर कदम एक अपवाद को दबा सकता है, जो वास्तव में `contextlib.suppress` के लिए क्या है और जब एक `with` ब्लॉक एक त्रुटि को निगलता है तो पहचानने के लायक है।

फ़ाइलें पढ़ना

पढ़ने के लिए तीन तरीके। .read() संपूर्ण फ़ाइल को एक स्ट्रिंग के रूप में लोड करता है। .readline() एक लाइन पढ़ता है। फ़ाइल ऑब्जेक्ट पर सीधे पुनरावृत्ति करने से लाइन दर लाइन पढ़ता है, जो बड़ी फ़ाइलों के लिए सबसे कुशल दृष्टिकोण है क्योंकि यह एक बार में सब कुछ मेमोरी में लोड नहीं करता है।

.read() संपूर्ण फ़ाइल को एक स्ट्रिंग के रूप में मेमोरी में लोड करता है। .readline() एक एकल लाइन पढ़ता है, नई लाइन सहित। .readlines() हर लाइन की एक सूची लौटाता है। किसी भी चीज़ के लिए जो बड़ी हो सकती है, फ़ाइल ऑब्जेक्ट पर सीधे पुनरावृत्ति करें for line in f: यह एक बार में एक लाइन खींचता है और पूरी फ़ाइल को कभी एक बार में नहीं रखता है, जो मेमोरी को फ्लैट रखता है चाहे कितना बड़ा हो।

.read() संपूर्ण फ़ाइल को एक स्ट्रिंग के रूप में लौटाता है, इसलिए इसकी मेमोरी लागत फ़ाइल आकार के साथ बढ़ता है: एक कॉन्फ़िग के लिए ठीक है, एक मल्टी-गीगाबाइट लॉग के लिए एक समस्या। फ़ाइल ऑब्जेक्ट पर पुनरावृत्ति, for line in f, एक बार में एक लाइन पढ़ता है और अगले से पहले इसे छोड़ देता है, इसलिए मेमोरी लंबाई की परवाह किए बिना फ्लैट रहती है। वह अनजान आकार की फ़ाइलों के लिए डिफ़ॉल्ट पैटर्न है। .readlines() सुविधाजनक लगता है लेकिन एक बार में हर लाइन की एक सूची बनाता है, जिसका मेमोरी फुटप्रिंट .read() जैसा ही है, इसलिए यह लूप के ऊपर आपको कुछ नहीं खरीदता है। नियम जो क्लासिक आउट-ऑफ-मेमोरी बग को रोकता है: for line in f लूप के लिए पहले पहुंचें, और केवल .read() को तब कॉल करें जब आप जानते हैं कि फ़ाइल छोटी है।

python
with open("data.txt", "r") as f:
    content = f.read()          # संपूर्ण फ़ाइल एक स्ट्रिंग के रूप में

with open("data.txt", "r") as f:
    first_line = f.readline()   # एक बार में एक लाइन

with open("data.txt", "r") as f:
    lines = f.readlines()       # हर लाइन के साथ लाइनों की सूची, "\n" में समाप्त

बड़ी फ़ाइलों के लिए, एक बार में सब कुछ लोड करने के बजाय लाइन दर लाइन पढ़ना अधिक कुशल है:

python
with open("big_file.txt", "r") as f:
    for line in f:              # फ़ाइल को सीधे दोहराएँ, मेमोरी-कुशल
        print(line.strip())     # strip() अनुगामी नई लाइन को हटाता है

फ़ाइल ऑब्जेक्ट पर सीधे पुनरावृत्ति (for line in f) एक बड़ी फ़ाइल पढ़ने का सबसे कुशल तरीका है।

Junoफ़ाइलें पढ़ना.read() आपको एक स्ट्रिंग के रूप में पूरी फ़ाइल देता है, .readline() आपको एक एकल लाइन देता है। जब फ़ाइल बड़ी हो सकती है, तो `for line in f` के साथ लूप करें, यह एक बार में एक लाइन पढ़ता है इसलिए आप कभी लॉट को मेमोरी में लोड नहीं करते हैं। प्रत्येक लाइन पर `.strip()` अनुगामी नई लाइन को साफ करता है।
Junoफ़ाइलें पढ़ना.read() एक बार में सब कुछ लोड करता है, जो छोटी फ़ाइलों के लिए ठीक है और बड़ी के लिए जोखिम भरा है। `for line in f` को डिफ़ॉल्ट करें: यह एक बार में एक लाइन स्ट्रीम करता है और आकार की परवाह किए बिना मेमोरी को फ्लैट रखता है। `.readlines()` सुंदर दिखता है लेकिन उतना ही मेमोरी का उपयोग करता है जितना `.read()`।
Junoफ़ाइलें पढ़ना `.read()` और `.readlines()` दोनों संपूर्ण फ़ाइल को मेमोरी में रखते हैं, इसलिए वे फ़ाइल आकार के साथ बढ़ते हैं। `for line in f` लूप एक बार में एक लाइन पढ़ता और छोड़ता है, मेमोरी को फ्लैट रखता है, जो आपको एक फ़ाइल पर आउट-ऑफ-मेमोरी आश्चर्य से बचाता है जिसे आपने पहले आकार नहीं दिया था। लूप को डिफ़ॉल्ट करें, `.read()` केवल तब जब आप जानते हैं कि वह छोटी है।

फ़ाइलें लिखना

"w" मोड संपूर्ण फ़ाइल को ओवरराइट करता है यदि यह मौजूद है। "a" मोड अंत में जोड़ता है। .write() स्वचालित रूप से नई लाइन नहीं जोड़ता है; प्रत्येक लाइन के अंत में स्पष्ट रूप से "\n" शामिल करें। कई लाइनों को एक बार में लिखने के लिए, "\n".join() के साथ उन्हें जोड़ें।

.write(s) एक स्ट्रिंग लिखता है और, print() के विपरीत, कुछ भी नहीं जोड़ता है, कोई स्पेस और कोई नई लाइन नहीं, तो आप स्वयं "\n" को लगाते हैं। .writelines(lines) एक सूची में प्रत्येक स्ट्रिंग को वापस एक दूसरे को लिखता है, फिर से कोई विभाजक नहीं जोड़े जाते हैं, इसलिए नई लाइनें पहले से ही आपकी स्ट्रिंग में होनी चाहिए। मोड पर ध्यान दें: "w" एक क्षण में फ़ाइल को साफ करता है, इससे पहले कि आप कुछ लिखते हैं, तो जब आप "w" के लिए पहुंचते हैं "a" के बजाय पुरानी सामग्री को त्याग देते हैं।

लिखने के बारे में दो चीजें जो असली बग का कारण बनती हैं। पहला, डेटा जो आप लिखते हैं वह आवश्यक रूप से तुरंत डिस्क पर नहीं जाता है: OS इसे एक बफर में रखता है और बैच में लिखता है, और यह .close() है (जो with आपके लिए कॉल करता है) जो सुनिश्चित करता है कि सब कुछ डिस्क पर है। यदि एक लंबे समय तक चलने वाली प्रक्रिया लिखती है और कभी बंद नहीं करती है, तो आउटपुट की पूंछ बफर में बैठ सकती है और एक क्रैश पर खो सकती है, तो फ़ाइल को बंद करें या जहां डेटा सुरक्षित होना चाहिए वहां .flush() को कॉल करें। दूसरा, मोड नुकसान तय करता है: "w" खुलने के क्षण में फ़ाइल को खाली करता है, किसी भी लेखन से पहले, तो जब आप "w" के लिए पहुंचते हैं "a" चाहते हैं तो पिछली सामग्री को बिना चेतावनी के नष्ट करते हैं। .writelines(lines) अपने आप में कोई विभाजक नहीं जोड़ता है, तो नई लाइनें पहले से ही स्ट्रिंग्स में होनी चाहिए।

python
with open("output.txt", "w") as f:
    f.write("नमस्ते, दुनिया\n")

with open("output.txt", "a") as f:
    f.write("एक और पंक्ति\n")

"w" फ़ाइल को पूरी तरह ओवरराइट करता है यदि यह मौजूद है। "a" अंत में जोड़ता है।

f.write() स्वचालित रूप से नई लाइन नहीं जोड़ता है, तो स्पष्ट रूप से "\n" शामिल करें। कई लाइनों को एक बार में लिखने के लिए:

python
lines = ["पहली पंक्ति", "दूसरी पंक्ति", "तीसरी पंक्ति"]

with open("output.txt", "w") as f:
    f.write("\n".join(lines) + "\n")
Junoफ़ाइलें लिखना"w" फ़ाइल को बनाता या ओवरराइट करता है, "a" इसे मिटाए बिना अंत में जोड़ता है। .write() आपके लिए नई लाइन नहीं जोड़ता है, तो प्रत्येक लाइन पर स्वयं `"\n"` लगाएँ। लाइनों के बैच के लिए, `"\n".join(lines)` उन्हें पहले एक साथ सिलाई करता है।
Junoफ़ाइलें लिखना `"w"` खुलने के क्षण में फ़ाइल को साफ करता है, `"a"` जोड़ता है, तो गलत को चुनना शांति से पुरानी सामग्री को फेंक देता है। .write() कुछ भी नहीं जोड़ता है, कोई नई लाइन नहीं, तो आप स्वयं `"\n"` आपूर्ति करते हैं। .writelines() एक सूची को बिना विभाजक के भी लिखता है, नई लाइनें पहले से ही स्ट्रिंग्स में होनी चाहिए।
Junoफ़ाइलें लिखना `"w"` खुलने के क्षण में फ़ाइल को खाली करता है, तो इसके बजाय `"a"` के लिए पहुंचना पिछली सामग्री को बिना चेतावनी के नष्ट करता है। लेखन बफर में बैठते हैं जब तक `.close()` (जो `with` कॉल करता है) उन्हें फ्लश नहीं करता है, तो एक प्रक्रिया जो लिखती है और कभी बंद नहीं करती है एक क्रैश पर अपनी पूंछ खो सकती है। .write() और .writelines() नई लाइनें नहीं जोड़ते, यह आप पर है।

अपवाद

जब पायथन एक समस्या का सामना करता है जिसे वह संभाल नहीं सकता, तो वह एक अपवाद उठाता है: एक त्रुटि जो बताती है कि क्या गलत हुआ और कहां। यदि आप इसे संभालते नहीं हैं, तो आपका प्रोग्राम क्रैश हो जाता है और एक ट्रेसबैक प्रिंट करता है। नीचे दी गई तालिका सबसे सामान्य अपवाद दिखाती है जिनका आप सामना करेंगे।

एक अपवाद एक ऑब्जेक्ट है, और अपवाद एक पारिवारिक पेड़ बनाते हैं: FileNotFoundError जैसे विशिष्ट एक व्यापक (OSError) का एक प्रकार हैं, और लगभग हर चीज़ जिसे आप पकड़ते हैं वह एक Exception का प्रकार है। यह पेड़ पकड़ने को कैसे काम करता है: एक माता-पिता प्रकार को पकड़ना भी इसके बच्चों को पकड़ता है। जब एक उठाया जाता है, तो पायथन वर्तमान लाइन को छोड़ देता है और कॉल के माध्यम से ऊपर की ओर चलता है जो वहाँ पहुंचा, एक मिलान करने वाला except खोज रहा है। यदि इसे कोई नहीं मिलता है, तो प्रोग्राम बंद हो जाता है और एक ट्रेसबैक प्रिंट करता है: जहां त्रुटि हुई वहां से शीर्ष तक के कॉल की सूची।

अपवाद एक वर्ग पदानुक्रम बनाते हैं (प्रकारों का एक पारिवारिक पेड़), और यह पेड़ पूरा खेल है जब आप उन्हें पकड़ते हैं: माता-पिता प्रकार के लिए एक except भी इसके नीचे हर प्रकार को पकड़ता है, तो except Exception एक विस्तृत नेट है और except FileNotFoundError एक संकीर्ण है। पेड़ का एक हिस्सा जो याद रखने के लायक है वह यह है कि KeyboardInterrupt (उपयोगकर्ता Ctrl-C दबा रहा है) और SystemExit (एक स्वच्छ शटडाउन अनुरोध) Exception के बगल में बैठते हैं, इसके अंदर नहीं। यह जानबूझकर है: इसका मतलब है कि एक व्यापक except Exception उन दोनों को जाने देता है, तो Ctrl-C अभी भी एक पकड़ के अंदर भी आपके प्रोग्राम को बंद करता है। यह वह कारण है कि आप except Exception के लिए पहुंचते हैं और कभी एक नंगे except: नहीं करते हैं, जो उन दोनों को पकड़ता है और उपयोगकर्ता को एक प्रोग्राम के अंदर फंसाता है जिसे बंद करने का वह प्रयास कर रहा है।

सामान्य अपवाद जिनका आप सामना करेंगे:

अपवादजब यह होता है
FileNotFoundErroropen() फ़ाइल नहीं खोज सकता
ValueErrorफ़ंक्शन को सही प्रकार का मान लेकिन गलत सामग्री मिली, उदाहरण के लिए int("abc")
TypeErrorपूरी तरह गलत प्रकार, उदाहरण के लिए "hello" + 5
KeyErrorशब्दकोश की कुंजी मौजूद नहीं है
IndexErrorसूची का सूचकांक सीमा से बाहर है
ZeroDivisionErrorशून्य से विभाजन
AttributeErrorऑब्जेक्ट के पास वह विशेषता या विधि नहीं है
Junoअपवाद एक अपवाद पायथन को बता रहा है कि कुछ गलत हुआ। आप लगातार कुछ से मिलेंगे: `FileNotFoundError`, `ValueError`, `KeyError`, `TypeError`। बिना संभाले वे प्रोग्राम को बंद करते हैं और एक ट्रेसबैक प्रिंट करते हैं, जो भयानक दिखता है लेकिन वास्तव में एक नक्शा है जो सीधे इंगित करता है कि यह कहां टूटा है।
Junoअपवाद अपवाद एक पारिवारिक पेड़ में व्यवस्थित ऑब्जेक्ट हैं, और माता-पिता प्रकार को पकड़ना भी इसके बच्चों को पकड़ता है। जब एक उठाया जाता है पायथन कॉल के माध्यम से ऊपर की ओर एक मिलान करने वाला `except` खोजता है, और यदि कोई नहीं मिलता है तो एक ट्रेसबैक प्रिंट करता है। सामान्य नाम जानना, `ValueError`, `KeyError`, `FileNotFoundError`, आपको सही को पकड़ने देता है।
Junoअपवाद प्रकार पदानुक्रम पूरा बिंदु है: `except Exception` विस्तृत नेट है, एक विशिष्ट प्रकार संकीर्ण है। `KeyboardInterrupt` और `SystemExit` `Exception` के बगल में बैठते हैं, इसके अंदर नहीं, तो Ctrl-C अभी भी `except Exception` से बाहर निकलता है। यह `except:` नंगे से उपयोग करने का कारण है, जो उपयोगकर्ता को एक प्रोग्राम के अंदर फंसाता है जिसे बंद करने का वह प्रयास कर रहा है।

try / except

कोड को लपेटें जो एक try ब्लॉक में विफल हो सकता है। यदि एक अपवाद होता है, तो मिलान करने वाला except ब्लॉक क्रैश होने के बजाय इसे संभालता है। विशिष्ट बनें कि आप कौन सा अपवाद पकड़ते हैं: एक नंगे except: के साथ सब कुछ पकड़ना असली बग को छिपाता है।

try/except एक विशिष्ट अपवाद प्रकार को पकड़ता है और क्रैश होने के बजाय हैंडलर चलाता है। प्रकार का नाम देना महत्वपूर्ण है: जिसे आप वास्तव में ठीक हो सकते हैं उसे पकड़ें, तो एक असंबंधित बग जोर से सामने आता है बजाय निगल जाने के। अपवाद को as e के साथ बाँधें जब आप इसका संदेश पढ़ना चाहते हैं। विभिन्न प्रकारों के लिए कई except खंड सूचीबद्ध करें और पायथन पहला उपयोग करता है जो फिट बैठता है।

एक except SomeType मेल खाता है जब उठाया गया अपवाद वह प्रकार या इसका एक उप-प्रकार है (पेड़ में इसके नीचे एक अधिक विशिष्ट प्रकार), यह कारण है कि माता-पिता को पकड़ना इसके सभी बच्चों को पकड़ता है। पायथन शीर्ष से नीचे तक प्रत्येक except कोशिश करता है और पहले मेल पर रुकता है, तो उन्हें विशिष्ट से पहले सामान्य रूप से आदेश दें: एक व्यापक खंड को पहले रखा गया सब कुछ पकड़ेगा और इसके नीचे संकीर्ण लोग कभी नहीं चलेंगे। अनुशासन जो try/except को बग को छिपाने से रोकता है: सबसे संकीर्ण प्रकार को पकड़ें जिसे आप संभाल सकते हैं, try शरीर को एक पंक्ति तक रखें जो वास्तव में उठा सकते हैं, और बाकी सब को प्रसारित करें। एक बीस पंक्तियों के चारों ओर try लपेटना एक अपेक्षित विफलता को उन्नीस अप्रत्याशित लोगों पर एक मुखौटा में बदल देता है।

python
try:
    value = int("abc")
except ValueError:
    print("वह एक वैध संख्या नहीं है")

विशिष्ट बनें कि आप कौन सा अपवाद पकड़ते हैं। एक नंगे except: के साथ सभी अपवाद को पकड़ना बग को छिपाता है:

python
# बुरा, सब कुछ पकड़ता है प्रोग्रामर की गलतियों सहित
try:
    result = do_something()
except:
    pass

# अच्छा, केवल जो आप उम्मीद करते हैं और वास्तव में संभाल सकते हैं उसे पकड़ता है
try:
    result = do_something()
except FileNotFoundError:
    print("फ़ाइल नहीं मिली")
Junotry / except कोड को `try` ब्लॉक में डालें जो विफल हो सकता है, और मिलान करने वाला `except` प्रोग्राम के क्रैश होने के बजाय चलता है। `ValueError` जैसे अपवाद का नाम दें, एक नंगे `except:` के बजाय, जो सब कुछ पकड़ता है और असली बग को आप से छिपाता है। जो कुछ आप वास्तव में व्यवहार कर सकते हैं उसे पकड़ें, और बाकी को दिखने दें।
Junotry / except `try`/`except` एक नामित प्रकार को पकड़ता है और क्रैश होने के बजाय ठीक हो जाता है; `as e` आपको संदेश देता है। जो विशिष्ट प्रकार आप संभाल सकते हैं उसे पकड़ें तो असंबंधित बग अभी भी सामने आते हैं। `try` शरीर को छोटा रखें, बीस पंक्तियों को लपेटना एक अपेक्षित विफलता को बाकी पर एक मुखौटा में बदल देता है।
Junotry / except एक `except` अपने प्रकार और किसी भी उप-प्रकार से मेल खाता है, और पायथन पहला खंड लेता है जो फिट बैठता है, तो विशिष्ट सामान्य से पहले आदेश दें या व्यापक को शेष पर छाया डालता है। सबसे संकीर्ण प्रकार को पकड़ें, `try` को उस लाइन तक रखें जो वास्तव में उठा सकते हैं, और बाकी को प्रसारित करें। एक विस्तृत `try` उस विफलता से कहीं अधिक को छिपाता है जिसे आप संभालना चाहते थे।

कई अपवादों को पकड़ना

आप अलग-अलग except ब्लॉक में विभिन्न त्रुटि प्रकारों को संभाल सकते हैं, या एक ट्यूपल का उपयोग करके एक ब्लॉक में कई प्रकारों को पकड़ सकते हैं। as e भाग आपको त्रुटि संदेश तक पहुंच देता है।

विभिन्न प्रकारों के लिए कई except खंड स्टैक करें और पायथन शीर्ष से नीचे तक जांच करता है, पहले जो फिट बैठता है उसे लेता है। एक ही तरीके से कई प्रकारों को संभालने के लिए, उन्हें एक ट्यूपल में समूहबद्ध करें: except (ValueError, ZeroDivisionError). as e अपवाद को बाँधता है तो आप इसका संदेश पढ़ सकते हैं। क्रम महत्वपूर्ण है: सामान्य से पहले विशिष्ट प्रकार रखें, या एक व्यापक खंड ऊपर सब कुछ पकड़ता है और नीचे वाले कभी नहीं चलते हैं।

क्रम जाल है। पायथन पहला except लेता है जिसका प्रकार मेल खाता है, और एक व्यापक प्रकार इसके संकीर्ण रिश्तेदारों से मेल खाता है, तो except Exception को except ValueError से ऊपर सूचीबद्ध करना ValueError खंड को मृत कोड में बदल देता है जो कभी नहीं चलता है। विशिष्ट पहले, सामान्य अंतिम। except (A, B) as e के साथ साझा प्रतिक्रिया वाले प्रकारों को समूहबद्ध करें। जब आप एक त्रुटि को केवल संदर्भ जोड़ने और गुजरने के लिए पकड़ते हैं, from के साथ नया बढ़ाएँ: raise ValueError("bad config") from e. यह मूल त्रुटि को ट्रेसबैक में नई के नीचे दृश्यमान रखता है, तो रिपोर्ट उच्च-स्तर का अर्थ और निम्न-स्तर का कारण दोनों दिखाती है बजाय एक को दूसरे से बदलने के।

python
try:
    data = int(user_input)
    result = 100 / data
except ValueError:
    print("एक संख्या नहीं")
except ZeroDivisionError:
    print("शून्य से विभाजित नहीं कर सकते")

या ट्यूपल में कई को पकड़ें:

python
except (ValueError, ZeroDivisionError) as e:
    print(f"इनपुट त्रुटि: {e}")

as e अपवाद ऑब्जेक्ट को एक नाम से बाँधता है तो आप संदेश का निरीक्षण कर सकते हैं।

Junoकई अपवादों को पकड़ना प्रत्येक त्रुटि प्रकार को अपने `except` ब्लॉक दें, और पायथन पहले को चलाता है जो मेल खाता है। कुछ को एक ही तरीके से संभालने के लिए, उन्हें ट्यूपल में सूचीबद्ध करें: `except (ValueError, ZeroDivisionError)`. `as e` भाग आपको त्रुटि ऑब्जेक्ट देता है तो आप इसका संदेश प्रिंट कर सकते हैं।
Junoकई अपवादों को पकड़ना कई `except` खंड शीर्ष से नीचे चलते हैं, पहला मेल जीतता है, तो सामान्य से पहले विशिष्ट प्रकार सूचीबद्ध करें या व्यापक बाकी को छायित करता है। एक ट्यूपल, `except (A, B)`, साझा प्रतिक्रिया के साथ कई को एक ब्लॉक से संभालता है। `as e` अपवाद को बाँधता है तो आप इसका संदेश पढ़ सकते हैं।
Junoकई अपवादों को पकड़ना विशिष्ट खंड पहले आते हैं: एक संकीर्ण के ऊपर व्यापक प्रकार संकीर्ण खंड को मृत कोड बनाता है। साझा प्रतिक्रिया को `except (A, B) as e` के साथ समूहबद्ध करें। जब आप संदर्भ जोड़ने के लिए फिर से उठाते हैं, तो `raise NewError("...") from e` का उपयोग करें तो मूल कारण नई त्रुटि के नीचे ट्रेसबैक में दृश्यमान रहता है बजाय गायब होने के।

else और finally

else केवल तभी चलता है जब कोई अपवाद न हुआ हो। finally हमेशा चलता है, अपवाद हो या न हो। finally उपयोगी है सफाई के लिए जो चाहे क्या हो होनी चाहिए।

else वह कोड रखता है जो तभी चलना चाहिए जब try शरीर ने कुछ नहीं उठाया हो। इसे try से बाहर रखना इरादा को स्पष्ट करता है: आप आकस्मिक रूप से अपने except खंड में से एक को सफलता पथ से ट्रिगर नहीं कर रहे हैं। finally सफाई गारंटी है, यह चाहे क्या हो चलता है, सफलता पर, एक पकड़े गए अपवाद पर, या यहां तक कि एक return को भी। यह वह है जो इसे एक संसाधन को जाने देने के लिए सही घर बनाता है जो परिणाम की परवाह किए बिना जाना चाहिए।

else केवल तभी चलता है जब try शरीर साफ-सुथरा समाप्त होता है, जो सफलता पथ के कोड को try से बाहर रखता है तो यह आकस्मिक रूप से आपके except खंड में से एक को ट्रिगर नहीं कर सकता है। finally बिना शर्त चलता है: सफलता के बाद, एक पकड़े गए अपवाद के बाद, एक अपकड़े गए के बाद भी इसके रास्ते में, यहां तक कि try में एक return के बाद। वह अंतिम मामला एक जाल को छिपाता है जो जानने के लायक है: finally से एक return को try से एक return को ओवरराइड करता है और, बदतर, शांति से एक अपवाद को दबाता है जो प्रसारित हो रहा था, तो त्रुटि बिना निशान के गायब हो जाती है। finally को सफाई के लिए रखें, कभी इससे return न करें। फ़ाइलों के लिए, with पहले से ही यह गारंटी देता है, तो मुख्य रूप से finally के लिए पहुंचें जब आप एक संसाधन रख रहे हैं जिसके पास कोई संदर्भ प्रबंधक नहीं है।

python
try:
    with open("data.txt") as f:
        content = f.read()
except FileNotFoundError:
    print("फ़ाइल नहीं मिली, डिफ़ॉल्ट का उपयोग कर रहे हैं")
    content = ""
else:
    print("फ़ाइल सफलतापूर्वक लोड की गई")
finally:
    print("फ़ाइल लोड करने का प्रयास पूरा हुआ")   # हमेशा चलता है

finally सफाई के लिए सबसे उपयोगी है (कनेक्शन बंद करना, लॉक जारी करना) भले ही आप पहले से ही फ़ाइलों के लिए with का उपयोग कर रहे हों।

Junoelse और finally `else` केवल तभी चलता है जब `try` ने कुछ नहीं उठाया, सफलता पथ के बाकी के लिए एक सुंदर जगह। `finally` हर बार चलता है, अपवाद हो या न हो, जो इसे सफाई के लिए जगह बनाता है जो चाहे क्या हो होनी चाहिए। फ़ाइलों के साथ `with` पहले से ही सफाई को कवर करता है, तो आप `finally` के लिए कम से कम उम्मीद से अधिक पहुंचेंगे।
Junoelse और finally `else` स्वच्छ पथ पर चलता है, सफलता कोड को `try` से बाहर रखता है तो यह आपके अपने `except` को ट्रिप नहीं कर सकता। `finally` बिना शर्त चलता है, यहां तक कि एक `return` के पिछले भी, तो यह आपकी सफाई गारंटी है। फ़ाइलों के लिए `with` पहले से ही यह करता है, तो संसाधनों के बिना `finally` को बचाएँ जिनके पास कोई संदर्भ प्रबंधक नहीं है।
Junoelse और finally `else` स्वच्छ पथ कोड है जो `try` से बाहर रहता है तो यह आपके `except` खंड को आग नहीं लगा सकता है। `finally` चाहे क्या हो चलता है, लेकिन कभी इससे `return` न करें: वह ओवरराइड एक प्रसारित अपवाद को दबाता है और त्रुटि शांति से गायब हो जाती है। `finally` को सफाई के लिए रखें, और मुख्य रूप से केवल जब कोई `with` नहीं हो।

raise

आप raise के साथ स्वयं अपवाद उठा सकते हैं। यह है कि आप अपने फ़ंक्शन को समस्याओं को स्पष्ट रूप से कॉलर को सिग्नल देने का तरीका है गलत मान को शांति से लौटाने के बजाय।

raise ExceptionType("message") आपके अपने कोड से एक अपवाद फेंकता है, जो कैसे एक फ़ंक्शन एक खराब इनपुट की रिपोर्ट करता है गलत मान के साथ लंगड़ा होने के बजाय। एक except ब्लॉक के अंदर, एक नंगा raise (कोई तर्क नहीं) अपवाद को फिर से फेंकता है जिसे आपने पकड़ा है, उपयोगी जब आप इसे लॉग करना चाहते हैं या प्रतिक्रिया करना चाहते हैं और फिर भी इसे आगे बढ़ने दें। जानबूझकर उठाना एक फ़ंक्शन की विफलता मोड को इसके अनुबंध का हिस्सा बनाता है, तो कॉलर उन्हें नाम से पकड़ और संभाल सकते हैं।

raise SomeError("message") जानबूझकर एक विफलता की रिपोर्ट करता है, सही कदम जब एक फ़ंक्शन को इनपुट मिलता है जिसे वह सम्मान नहीं कर सकता: जोर से मना करना एक गलत उत्तर को लौटाने से बेहतर है जो बाद में एक रहस्य के रूप में सामने आता है। एक except के अंदर, एक नंगा raise अपवाद को फिर से फेंकता है जिसे आपने अपने मूल ट्रेसबैक को बरकरार रखते हुए पकड़ा है, तो आप लॉग कर सकते हैं और फिर से उठा सकते हैं बिना मिटाए कि यह कहां आया है। जब आप एक निम्न-स्तर की त्रुटि को एक डोमेन में अनुवाद करना चाहते हैं, from का उपयोग करें: raise ConfigError("bad settings") from e मूल को नई के नीचे रिपोर्ट में रखता है, तो एक पाठक अर्थ और कारण दोनों को देखता है। अंगूठे का नियम: प्रसंग जोड़ने के लिए फिर से उठाएँ, कभी इसे छिपाने के लिए नहीं।

python
def divide(a, b):
    if b == 0:
        raise ValueError("शून्य से विभाजित नहीं कर सकते")
    return a / b

यह आपके फ़ंक्शन को स्पष्ट बनाता है कि वे क्या उम्मीद करते हैं और समस्याओं को कॉलर को स्पष्ट रूप से सिग्नल देते हैं।

Junoraise `raise ExceptionType("message")` आपके अपने कोड को एक समस्या को जोर से झंडी देने देता है गलत मान के साथ जारी रखने के बजाय। यह है कि एक फ़ंक्शन कहता है "मैं इससे काम नहीं कर सकता" तो कॉलर इसे व्यवहार करता है। स्पष्ट और जल्दी एक गलत उत्तर से बेहतर है जो बहुत बाद में दिखता है।
Junoraise `raise ExceptionType("message")` आपके कोड से एक विफलता की रिपोर्ट करता है, कॉलर कैसे इसे उपयोग करते हैं इसका एक फ़ंक्शन का अनुबंध बनाता है। एक नंगा `raise` एक `except` के अंदर फिर से फेंकता है जिसे आपने पकड़ा है, मूल ट्रेसबैक को रखता है, तो आप लॉग कर सकते हैं और अभी भी इसे आगे बढ़ने दें।
Junoraise जानबूझकर उठाएँ जब इनपुट को सम्मान नहीं किया जा सकता: जोर से मना करना एक गलत उत्तर से बेहतर है जो बाद में एक रहस्य के रूप में सामने आता है। एक नंगा `raise` मूल ट्रेसबैक को बरकरार रखते हुए फिर से फेंकता है। एक निम्न-स्तर की त्रुटि को डोमेन में अनुवाद करने के लिए, `raise DomainError("...") from e` का उपयोग करें तो कारण दृश्यमान रहता है, संदर्भ जोड़ने के लिए फिर से उठाएँ, कभी दफन न करें।

कस्टम अपवाद वर्ग

बड़े प्रोग्राम के लिए, आप Exception से विरासत में देकर अपने स्वयं के अपवाद प्रकार को परिभाषित कर सकते हैं। यह कॉलर को अपनी विशिष्ट त्रुटियों को अन्य प्रकार की त्रुटियों से अलग से पकड़ने देता है।

एक कस्टम अपवाद आपका अपना वर्ग है जो Exception से विरासत में लेता है (यह एक नए प्रकार का अपवाद बन जाता है, तो यह पारिवारिक पेड़ में स्लॉट करता है)। पेऑफ एक नाम है जिसे कॉलर सटीक रूप से पकड़ सकता है, अंतर्निहित त्रुटियों से अलग। संबंधित विफलताओं के एक समूह के लिए, एक आधार वर्ग बनाएँ और प्रत्येक विशिष्ट मामले के लिए इसे उप-वर्ग करें: कॉलर पूरे समूह को संभालने के लिए आधार को पकड़ सकते हैं, या एक विशेष के लिए उप-वर्ग, अंतर्निहित त्रुटियों को अलग किए बिना।

Exception को उप-वर्ग करें, BaseException को नहीं (रूट जो Ctrl-C और शटडाउन को भी कवर करता है, जिसे आप अपनी त्रुटि को साथ समूहबद्ध नहीं करना चाहते हैं)। आपका अपना प्रकार परिभाषित करने का कारण ValueError को फिर से उपयोग करने के बजाय पारिवारिक पेड़ है: PaymentError जैसे आधार बनाएँ और प्रत्येक मोड (InsufficientFundsError, CardDeclinedError) के लिए इसे उप-वर्ग करें, और एक कॉलर PaymentError को पकड़ सकता है पूरी श्रेणी को संभालने के लिए या संदेश तारों को पार्स किए बिना एक उप-वर्ग को एक मामले के लिए, जो त्रुटि को कुछ बनाता है जो एक प्रोग्राम केवल प्रिंट करने के बजाय कार्य कर सकता है। क्लास को __init__ से देते हैं प्रासंगिक फ़ील्ड (खाता, राशि) को सहन करते हैं तो हैंडलर पाठ को खुरचने के बजाय कोड में जो हुआ उसका निरीक्षण कर सकते हैं, जो त्रुटि को कुछ बनाता है जो एक प्रोग्राम केवल प्रिंट करने के बजाय कार्य कर सकता है।

python
class InsufficientFundsError(Exception):
    pass

class BankAccount:
    def __init__(self, balance):
        self.balance = balance

    def withdraw(self, amount):
        if amount > self.balance:
            raise InsufficientFundsError(
                f"नहीं निकाल सकते {amount}, शेष है {self.balance}"
            )
        self.balance -= amount
python
try:
    account.withdraw(1000)
except InsufficientFundsError as e:
    print(f"लेन-देन अस्वीकृत: {e}")
Junoकस्टम अपवाद वर्ग `Exception` से विरासत में देकर अपना अपवाद प्रकार बनाएँ, और एक भी खाली वर्ग का मुख्य भाग शुरू करने के लिए काफी है। यह कॉलर को एक नाम देता है जो है तुम्हारा, अंतर्निहित त्रुटियों से अलग, तो आपके प्रोग्राम की समस्याएं अपने पर खड़ी हैं।
Junoकस्टम अपवाद वर्ग एक कस्टम अपवाद `Exception` से विरासत में लेने वाली एक कक्षा है, कॉलर को एक सटीक नाम पकड़ने देता है। संबंधित विफलताओं के लिए, एक आधार वर्ग बनाएँ और प्रति मामले उप-वर्ग करें: समूह के लिए आधार को पकड़ें, एक के लिए उप-वर्ग। आप संदेश स्ट्रिंग से परे विवरण ले जाने के लिए फ़ील्ड जोड़ सकते हैं।
Junoकस्टम अपवाद वर्ग `BaseException` को नहीं `Exception` को उप-वर्ग करें, तो आपकी त्रुटि Ctrl-C के साथ लंपित नहीं होती है। अपना परिभाषित करने का कारण `ValueError` को फिर से उपयोग करने के बजाय पेड़ है: एक `PaymentError` आधार विशिष्ट उप-वर्गों के साथ कॉलर को श्रेणी या एक मामले को संदेश पार्सिंग के बिना संभालने देता है। प्रासंगिक फ़ील्ड को `__init__` में रखें तो हैंडलर डेटा पर कार्य करते हैं, स्ट्रिंग पर नहीं।

JSON

JSON वह प्रारूप है जो हर कोई बोलता है: API, कॉन्फ़िग फ़ाइलें, डेटा निर्यात। पायथन का json मॉड्यूल इसे सीधे संभालता है। json.load() एक फ़ाइल से JSON को पायथन शब्दकोश या सूची में पढ़ता है। json.dump() एक शब्दकोश या सूची को JSON के रूप में एक फ़ाइल में वापस लिखता है।

जोड़े विभाजन करते हैं जो वे स्पर्श करते हैं। json.load() / json.dump() एक फ़ाइल ऑब्जेक्ट के साथ काम करते हैं, json.loads() / json.dumps() (जो s वाले हैं) मेमोरी में एक स्ट्रिंग के साथ काम करते हैं। जब एक मानव आउटपुट पढ़ेगा तो dump/dumps को indent=2 पास करें, अन्यथा यह एक पंक्ति पर आता है। अमान्य JSON json.JSONDecodeError बढ़ाता है, जो ValueError का एक प्रकार है, तो ValueError को पकड़ने वाला हैंडलर पहले से ही इसे कवर करता है।

चार नाम दो संचालन पार हैं दो स्रोतों के साथ: फ़ाइलों के लिए load/dump, स्ट्रिंग्स के लिए loads/dumps (s "स्ट्रिंग" के लिए है)। विस्तार जो उत्पादन में लोगों को पकड़ता है वह है JSON क्या प्रतिनिधित्व नहीं कर सकता। इसके पास एक तारीख, एक set, या एक Decimal की धारणा नहीं है, तो json.dumps(datetime.now()) TypeError बढ़ाता है। आप इसे default= पास करके संभालते हैं, एक फ़ंक्शन dump/dumps किसी भी मान को कॉल करता है जिसे वह नहीं जानता है, जो कुछ JSON रख सकता है लौटना चाहिए, आमतौर पर str(value)। अन्य नियम जो रखने के लायक है: संख्याएं float के रूप में राउंड-ट्रिप करती हैं, तो एक मान जिसे आपने सटीकता के लिए Decimal के रूप में लिखा था वह एक float के रूप में वापस आता है और इसे खो देता है। कभी पैसे या कुछ भी जिसे सटीक दशमलव की आवश्यकता है (देखें Numbers अध्याय) को एक सादे JSON संख्या के रूप में संग्रहीत न करें।

एक फ़ाइल से JSON पढ़ें:

python
import json

with open("config.json", "r") as f:
    config = json.load(f)    # JSON को पायथन dict/list में पार्स करता है

print(config["setting"])

JSON को एक फ़ाइल में लिखें:

python
import json

data = {"name": "राज", "score": 87, "active": True}

with open("output.json", "w") as f:
    json.dump(data, f, indent=2)    # indent= इसे मानव-पठनीय बनाता है

JSON से पायथन प्रकार मैपिंग:

JSONपायथन
object {}dict
array []list
string ""str
numberint या float
true / falseTrue / False
nullNone

एक फ़ाइल को स्पर्श किए बिना JSON स्ट्रिंग्स और पायथन ऑब्जेक्ट के बीच परिवर्तित करने के लिए:

python
import json

# स्ट्रिंग से पायथन
data = json.loads('{"name": "राज", "score": 87}')

# पायथन से स्ट्रिंग
text = json.dumps({"name": "राज", "score": 87}, indent=2)

json.load() एक फ़ाइल ऑब्जेक्ट से पढ़ता है। json.loads() (एक "s" के साथ) एक स्ट्रिंग से पढ़ता है।

JunoJSON `json.load(f)` JSON को एक फ़ाइल में पायथन dicts और lists में बदलता है, `json.dump(data, f)` उन्हें वापस लिखता है। `s` संस्करण, `json.loads` और `json.dumps`, एक फ़ाइल के बजाय एक स्ट्रिंग के लिए समान काम करते हैं। `indent=2` जोड़ें जब आप आउटपुट को पठनीय चाहते हैं।
JunoJSON `load`/`dump` फ़ाइलों को संभालते हैं, `loads`/`dumps` स्ट्रिंग्स को संभालते हैं, `s` स्ट्रिंग के लिए है। `indent=2` इसे मानव-पठनीय बनाता है। बुरा JSON `json.JSONDecodeError` बढ़ाता है, जो `ValueError` है, तो `ValueError` को पकड़ना पहले से ही एक पार्स विफलता को कवर करता है।
JunoJSON दो संचालन दो स्रोतों के साथ क्रॉस किए गए: फ़ाइलों के लिए `load`/`dump`, स्ट्रिंग्स के लिए `loads`/`dumps`। JSON के पास तारीख, समूह, या `Decimal` नहीं है, तो उन्हें डंप करने से `TypeError` बढ़ता है जब तक आप `default=` पास नहीं करते हैं। और संख्याएं `float` के रूप में राउंड-ट्रिप करती हैं, तो कभी पैसे को एक सादे JSON संख्या के रूप में संग्रहीत न करें, वापसी पर इसे सटीकता खो देती है।

अभ्यास में

एक छोटे खेल के लिए सेव/लोड पैटर्न: राज्य को JSON में लिखें, अगली बार लोड करें, और यदि कोई सेव फ़ाइल अभी तक मौजूद नहीं है तो डिफ़ॉल्ट पर वापस जाएँ:

python
import json

SAVE_FILE = "save_game.json"

def save_game(player_data: dict) -> None:
    with open(SAVE_FILE, "w") as f:
        json.dump(player_data, f, indent=2)
    print("खेल सहेजा गया।")

def load_game() -> dict:
    try:
        with open(SAVE_FILE, "r") as f:
            return json.load(f)
    except FileNotFoundError:
        print("कोई सेव फ़ाइल नहीं मिली, ताजा शुरू कर रहे हैं।")
        return {"name": "खिलाड़ी", "score": 0, "level": 1}

state = load_game()
state["score"] += 50
save_game(state)

कॉन्फ़िग फ़ाइल लोड करना और परिणाम सहेजना, प्रत्येक विफलता मोड के लिए विशिष्ट अपवाद हैंडलिंग के साथ:

python
import json

def load_config(path: str) -> dict:
    try:
        with open(path, "r") as f:
            return json.load(f)
    except FileNotFoundError:
        raise FileNotFoundError(f"कॉन्फ़िग फ़ाइल नहीं मिली: {path}")
    except json.JSONDecodeError as e:
        raise ValueError(f"में अमान्य JSON {path}: {e}")

def save_results(results: list[dict], path: str) -> None:
    with open(path, "w") as f:
        json.dump(results, f, indent=2)
    print(f"सहेजा गया {len(results)} परिणाम को {path}")

config = load_config("experiment.json")
results = [{"epoch": 1, "loss": 0.82}, {"epoch": 2, "loss": 0.61}]
save_results(results, "results.json")

एक संरचित लॉग लेखक जो एक फ़ाइल में टाइमस्टैम्प किए गए प्रविष्टियों को संलग्न करता है, एक शीर्ष-स्तरीय हैंडलर के साथ जो अप्रत्याशित विफलताओं को पकड़ता है और लॉग करता है:

python
import json
from datetime import datetime

LOG_FILE = "run.log"

def log(level: str, message: str) -> None:
    ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    entry = f"[{ts}] [{level.upper():7}] {message}\n"
    with open(LOG_FILE, "a") as f:
        f.write(entry)

def process(config_path: str) -> None:
    log("info", f"कार्य शुरू कर रहे हैं, कॉन्फ़िग: {config_path}")
    try:
        with open(config_path) as f:
            config = json.load(f)
        log("info", f"कॉन्फ़िग लोड किया गया: {config}")
    except FileNotFoundError:
        log("error", f"कॉन्फ़िग नहीं मिला: {config_path}")
        raise
    except json.JSONDecodeError as e:
        log("error", f"कॉन्फ़िग में बुरा JSON: {e}")
        raise

try:
    process("config.json")
except Exception as e:
    log("critical", f"कार्य विफल: {e}")

लॉगिंग के बाद फिर से उठाना मूल ट्रेसबैक को कॉलर के लिए संरक्षित रखता है। शीर्ष-स्तरीय except Exception किसी भी चीज़ को पकड़ता है जो गायब हुई, इसे महत्वपूर्ण के रूप में लॉग करता है, और प्रक्रिया को साफ-सुथरे तरीके से बाहर निकलने देता है।