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

ज्यादातर प्रोग्राम जो असली काम करते हैं वह फ़ाइल सिस्टम को छूते हैं: कॉन्फ़िग पढ़ना, परिणाम लिखना, डेटा लोड करना। और जब चीजें गलत हो जाती हैं, तो पायथन एक अपवाद उठाता है, एक संकेत कि कुछ अप्रत्याशित हुआ। यह अध्याय दोनों को कवर करता है: फ़ाइलों में और बाहर डेटा प्राप्त करना, और ऐसा कोड लिखना जो त्रुटियों को सुंदरता से संभालता है, क्रैश होने के बजाय।
फ़ाइलें खोलना
open() एक फ़ाइल खोलता है और एक ऑब्जेक्ट वापस करता है जिससे आप पढ़ या लिख सकते हैं। आप इसे पथ बताते हैं और आप फ़ाइल के साथ क्या करना चाहते हैं (पढ़ें, लिखें, या जोड़ें)। जब आप हो जाएं तो हमेशा एक फ़ाइल बंद करें; with कथन यह स्वचालित रूप से करता है।
f = open("data.txt", "r") # "r" = पढ़ें
content = f.read()
f.close()"r" मोड है:
| मोड | अर्थ |
|---|---|
"r" | पढ़ें। फ़ाइल मौजूद होनी चाहिए। डिफ़ॉल्ट मोड। |
"w" | लिखें। फ़ाइल को बनाता या ओवरराइट करता है। |
"a" | जोड़ें। बिना मिटाए अंत में जोड़ता है। |
"x" | बनाएँ। फ़ाइल पहले से मौजूद होने पर विफल हो जाता है। |
"r+" | पढ़ें और लिखें। |
"b" | बाइनरी। किसी भी मोड में जोड़ें: "rb", "wb"। |
जब आप हो जाएं तो हमेशा .close() को कॉल करें। इसे भूलने से फ़ाइल खुली रह जाती है और डेटा खो सकता है जो अभी भी लिखे जाने की प्रतीक्षा में है। इसे संभालने का विश्वसनीय तरीका with कथन है।
open(path, mode) आपको एक फ़ाइल ऑब्जेक्ट देता है, और मोड कहता है कि आप क्या करना चाहते हैं: पढ़ने के लिए "r", लिखने के लिए "w" (जो वहाँ जो कुछ है उसे मिटा देता है), अंत में जोड़ने के लिए "a"। मैंने एक बार एक फ़ाइल खो दी थी "w" से तब जब मेरा मतलब "a" था, तो मोड को टाइप करने से पहले कल्पना करें। with कथन
with open(...) फ़ाइल का प्रबंधन आपके लिए करता है, इंडेंटेड ब्लॉक समाप्त होने पर इसे स्वचालित रूप से बंद करता है, भले ही एक त्रुटि हो। हमेशा with open(...) का उपयोग करें मैनुअल open()/close() के बजाय। यह सुरक्षित है और यह मानक है।
with open("data.txt", "r") as f:
content = f.read()
# f यहाँ बंद है, गारंटीशुदाwith पायथन का संदर्भ प्रबंधक वाक्यविन्यास है: यह आपके लिए सेटअप और टियरडाउन कोड चलाता है, यहाँ फ़ाइल को खोलता है और विश्वसनीय रूप से इसे बंद करता है। इसे आंतरिक रूप से कैसे काम करता है यह जानने की आवश्यकता नहीं है इसे open() के साथ उपयोग करने के लिए।
with open(...) as f फ़ाइल को खोलता है, आपको इंडेंटेड ब्लॉक के अंदर f के साथ काम करने देता है, फिर ब्लॉक समाप्त होने पर इसे बंद करता है, भले ही कुछ गलत हो जाए। इसके बजाय स्वयं `.close()` को कॉल करना हर बार बेहतर है, यह भूलने के लिए एक कम चीज है। फ़ाइलें पढ़ना
पढ़ने के लिए तीन तरीके। .read() संपूर्ण फ़ाइल को एक स्ट्रिंग के रूप में लोड करता है। .readline() एक लाइन पढ़ता है। फ़ाइल ऑब्जेक्ट पर सीधे पुनरावृत्ति करने से लाइन दर लाइन पढ़ता है, जो बड़ी फ़ाइलों के लिए सबसे कुशल दृष्टिकोण है क्योंकि यह एक बार में सब कुछ मेमोरी में लोड नहीं करता है।
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" में समाप्तबड़ी फ़ाइलों के लिए, एक बार में सब कुछ लोड करने के बजाय लाइन दर लाइन पढ़ना अधिक कुशल है:
with open("big_file.txt", "r") as f:
for line in f: # फ़ाइल को सीधे दोहराएँ, मेमोरी-कुशल
print(line.strip()) # strip() अनुगामी नई लाइन को हटाता हैफ़ाइल ऑब्जेक्ट पर सीधे पुनरावृत्ति (for line in f) एक बड़ी फ़ाइल पढ़ने का सबसे कुशल तरीका है।
.read() आपको एक स्ट्रिंग के रूप में पूरी फ़ाइल देता है, .readline() आपको एक एकल लाइन देता है। जब फ़ाइल बड़ी हो सकती है, तो `for line in f` के साथ लूप करें, यह एक बार में एक लाइन पढ़ता है इसलिए आप कभी लॉट को मेमोरी में लोड नहीं करते हैं। प्रत्येक लाइन पर `.strip()` अनुगामी नई लाइन को साफ करता है। फ़ाइलें लिखना
"w" मोड संपूर्ण फ़ाइल को ओवरराइट करता है यदि यह मौजूद है। "a" मोड अंत में जोड़ता है। .write() स्वचालित रूप से नई लाइन नहीं जोड़ता है; प्रत्येक लाइन के अंत में स्पष्ट रूप से "\n" शामिल करें। कई लाइनों को एक बार में लिखने के लिए, "\n".join() के साथ उन्हें जोड़ें।
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" शामिल करें। कई लाइनों को एक बार में लिखने के लिए:
lines = ["पहली पंक्ति", "दूसरी पंक्ति", "तीसरी पंक्ति"]
with open("output.txt", "w") as f:
f.write("\n".join(lines) + "\n")"w" फ़ाइल को बनाता या ओवरराइट करता है, "a" इसे मिटाए बिना अंत में जोड़ता है। .write() आपके लिए नई लाइन नहीं जोड़ता है, तो प्रत्येक लाइन पर स्वयं `"\n"` लगाएँ। लाइनों के बैच के लिए, `"\n".join(lines)` उन्हें पहले एक साथ सिलाई करता है। अपवाद
जब पायथन एक समस्या का सामना करता है जिसे वह संभाल नहीं सकता, तो वह एक अपवाद उठाता है: एक त्रुटि जो बताती है कि क्या गलत हुआ और कहां। यदि आप इसे संभालते नहीं हैं, तो आपका प्रोग्राम क्रैश हो जाता है और एक ट्रेसबैक प्रिंट करता है। नीचे दी गई तालिका सबसे सामान्य अपवाद दिखाती है जिनका आप सामना करेंगे।
सामान्य अपवाद जिनका आप सामना करेंगे:
| अपवाद | जब यह होता है |
|---|---|
FileNotFoundError | open() फ़ाइल नहीं खोज सकता |
ValueError | फ़ंक्शन को सही प्रकार का मान लेकिन गलत सामग्री मिली, उदाहरण के लिए int("abc") |
TypeError | पूरी तरह गलत प्रकार, उदाहरण के लिए "hello" + 5 |
KeyError | शब्दकोश की कुंजी मौजूद नहीं है |
IndexError | सूची का सूचकांक सीमा से बाहर है |
ZeroDivisionError | शून्य से विभाजन |
AttributeError | ऑब्जेक्ट के पास वह विशेषता या विधि नहीं है |
try / except
कोड को लपेटें जो एक try ब्लॉक में विफल हो सकता है। यदि एक अपवाद होता है, तो मिलान करने वाला except ब्लॉक क्रैश होने के बजाय इसे संभालता है। विशिष्ट बनें कि आप कौन सा अपवाद पकड़ते हैं: एक नंगे except: के साथ सब कुछ पकड़ना असली बग को छिपाता है।
try:
value = int("abc")
except ValueError:
print("वह एक वैध संख्या नहीं है")विशिष्ट बनें कि आप कौन सा अपवाद पकड़ते हैं। एक नंगे except: के साथ सभी अपवाद को पकड़ना बग को छिपाता है:
# बुरा, सब कुछ पकड़ता है प्रोग्रामर की गलतियों सहित
try:
result = do_something()
except:
pass
# अच्छा, केवल जो आप उम्मीद करते हैं और वास्तव में संभाल सकते हैं उसे पकड़ता है
try:
result = do_something()
except FileNotFoundError:
print("फ़ाइल नहीं मिली")कई अपवादों को पकड़ना
आप अलग-अलग except ब्लॉक में विभिन्न त्रुटि प्रकारों को संभाल सकते हैं, या एक ट्यूपल का उपयोग करके एक ब्लॉक में कई प्रकारों को पकड़ सकते हैं। as e भाग आपको त्रुटि संदेश तक पहुंच देता है।
try:
data = int(user_input)
result = 100 / data
except ValueError:
print("एक संख्या नहीं")
except ZeroDivisionError:
print("शून्य से विभाजित नहीं कर सकते")या ट्यूपल में कई को पकड़ें:
except (ValueError, ZeroDivisionError) as e:
print(f"इनपुट त्रुटि: {e}")as e अपवाद ऑब्जेक्ट को एक नाम से बाँधता है तो आप संदेश का निरीक्षण कर सकते हैं।
else और finally
else केवल तभी चलता है जब कोई अपवाद न हुआ हो। finally हमेशा चलता है, अपवाद हो या न हो। finally उपयोगी है सफाई के लिए जो चाहे क्या हो होनी चाहिए।
try:
with open("data.txt") as f:
content = f.read()
except FileNotFoundError:
print("फ़ाइल नहीं मिली, डिफ़ॉल्ट का उपयोग कर रहे हैं")
content = ""
else:
print("फ़ाइल सफलतापूर्वक लोड की गई")
finally:
print("फ़ाइल लोड करने का प्रयास पूरा हुआ") # हमेशा चलता हैfinally सफाई के लिए सबसे उपयोगी है (कनेक्शन बंद करना, लॉक जारी करना) भले ही आप पहले से ही फ़ाइलों के लिए with का उपयोग कर रहे हों।
raise
आप raise के साथ स्वयं अपवाद उठा सकते हैं। यह है कि आप अपने फ़ंक्शन को समस्याओं को स्पष्ट रूप से कॉलर को सिग्नल देने का तरीका है गलत मान को शांति से लौटाने के बजाय।
def divide(a, b):
if b == 0:
raise ValueError("शून्य से विभाजित नहीं कर सकते")
return a / bयह आपके फ़ंक्शन को स्पष्ट बनाता है कि वे क्या उम्मीद करते हैं और समस्याओं को कॉलर को स्पष्ट रूप से सिग्नल देते हैं।
कस्टम अपवाद वर्ग
बड़े प्रोग्राम के लिए, आप Exception से विरासत में देकर अपने स्वयं के अपवाद प्रकार को परिभाषित कर सकते हैं। यह कॉलर को अपनी विशिष्ट त्रुटियों को अन्य प्रकार की त्रुटियों से अलग से पकड़ने देता है।
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 -= amounttry:
account.withdraw(1000)
except InsufficientFundsError as e:
print(f"लेन-देन अस्वीकृत: {e}")JSON
JSON वह प्रारूप है जो हर कोई बोलता है: API, कॉन्फ़िग फ़ाइलें, डेटा निर्यात। पायथन का json मॉड्यूल इसे सीधे संभालता है। json.load() एक फ़ाइल से JSON को पायथन शब्दकोश या सूची में पढ़ता है। json.dump() एक शब्दकोश या सूची को JSON के रूप में एक फ़ाइल में वापस लिखता है।
एक फ़ाइल से JSON पढ़ें:
import json
with open("config.json", "r") as f:
config = json.load(f) # JSON को पायथन dict/list में पार्स करता है
print(config["setting"])JSON को एक फ़ाइल में लिखें:
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 |
| number | int या float |
true / false | True / False |
null | None |
एक फ़ाइल को स्पर्श किए बिना JSON स्ट्रिंग्स और पायथन ऑब्जेक्ट के बीच परिवर्तित करने के लिए:
import json
# स्ट्रिंग से पायथन
data = json.loads('{"name": "राज", "score": 87}')
# पायथन से स्ट्रिंग
text = json.dumps({"name": "राज", "score": 87}, indent=2)json.load() एक फ़ाइल ऑब्जेक्ट से पढ़ता है। json.loads() (एक "s" के साथ) एक स्ट्रिंग से पढ़ता है।
अभ्यास में
एक छोटे खेल के लिए सेव/लोड पैटर्न: राज्य को JSON में लिखें, अगली बार लोड करें, और यदि कोई सेव फ़ाइल अभी तक मौजूद नहीं है तो डिफ़ॉल्ट पर वापस जाएँ:
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)
