# Python में JSON: फ़ाइलें पढ़ना और लिखना, CSV, pathlib और UTF-8 एन्कोडिंग

URL: https://skillaria.top/hi/guides/python/json-python

Python में JSON के लिए स्टैंडर्ड मॉड्यूल json है: json.load फ़ाइल से डेटा पढ़ता है, json.dump फ़ाइल में लिखता है, और json.loads व json.dumps यही काम स्ट्रिंग के साथ करते हैं। फ़ाइल को with open(path, encoding="utf-8") से खोलें, पथ pathlib.Path से बनाएँ, और सारणी (टेबल) वाला डेटा csv मॉड्यूल से पढ़ें।

Python में JSON के साथ काम करने के लिए किसी बाहरी लाइब्रेरी की ज़रूरत नहीं: मॉड्यूल `json` स्टैंडर्ड लाइब्रेरी में है, और डिक्शनरी व लिस्ट को टेक्स्ट में और वापस बदलता है। इसके साथ लगभग हमेशा तीन चीज़ें और चाहिए होती हैं: `with` के साथ `open` फ़ंक्शन, पथों के लिए `pathlib`, और सारणी के लिए `csv` मॉड्यूल। नीचे सब कुछ क्रम से है, चलने वाले कोड और उन गड्ढों के साथ जिनमें लोग सबसे ज़्यादा गिरते हैं।

## Python में open फ़ंक्शन: मोड और एन्कोडिंग

कोई भी टेक्स्ट फ़ाइल बिल्ट-इन फ़ंक्शन `open(path, mode, encoding=...)` से खुलती है। वह एक फ़ाइल ऑब्जेक्ट लौटाता है, जिसमें `read`, `readline`, `write` मेथड होते हैं और जिस पर लूप पंक्ति-दर-पंक्ति चलाया जा सकता है।

| मोड | क्या करता है |
| --- | --- |

| `"r"` | पढ़ना (डिफ़ॉल्ट)। फ़ाइल न हो तो `FileNotFoundError` |

| `"w"` | लिखना। फ़ाइल बनती है या **खुलते ही खाली हो जाती है** |

| `"a"` | अंत में जोड़ना, पुराना कंटेंट वैसा ही रहता है |

| `"x"` | नई फ़ाइल बनाना; पहले से हो तो `FileExistsError` |

| `"b"` | मोड में जोड़ा जाता है: बाइट्स के साथ काम (`"rb"`, `"wb"`) |

### with क्यों ज़रूरी है

फ़ाइल को बंद करना ज़रूरी है: वरना डेटा शायद डिस्क पर न पहुँचे, और सिस्टम डिस्क्रिप्टर अटका रहता है। `with` फ़ाइल को अपने-आप बंद करता है — ब्लॉक के भीतर एरर आने पर भी।

```
with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("पहली पंक्ति\n")
    f.write("दूसरी पंक्ति\n")

with open("notes.txt", encoding="utf-8") as f:
    for line in f:
        print(line.rstrip("\n"))
```

फ़ाइल पर लूप चलाने से वह एक-एक पंक्ति पढ़ी जाती है और पूरी मेमोरी में नहीं आती, इसलिए गीगाबाइट वाले लॉग भी इसी तरह संसाधित हो सकते हैं। `f.read()` पूरा कंटेंट एक स्ट्रिंग में देता है, और `f.readlines()` पंक्तियों की सूची।

### फ़ाइल में स्ट्रिंग जोड़ना, पुराना न मिटाना

सबसे आम गलती: कुछ «जोड़ने» के लिए फ़ाइल को `"w"` मोड में खोल देना। मोड `"w"` खोलते ही फ़ाइल को खाली कर देता है, पहले `write` से पहले ही। अंत में जोड़ने के लिए `"a"` लें, और किसी मौजूदा फ़ाइल को गलती से न बदलने के लिए `"x"`।

```
with open("log.txt", "a", encoding="utf-8") as f:
    f.write("नई प्रविष्टि\n")
```

ध्यान रहे, `write` ख़ुद नई पंक्ति नहीं जोड़ता — `"\n"` साफ़ लिखना होता है। या `print(..., file=f)` इस्तेमाल करें, वह लाइन-ब्रेक अपने-आप लगा देता है।

## UTF-8 एन्कोडिंग: «क्रैक्षोज़ब्रा» कहाँ से आते हैं

Python 3.15 से पहले `open()` में `encoding` न हो, तो वह सिस्टम की एन्कोडिंग लेता था। Linux और macOS पर यह UTF-8 है, पर Windows पर हिंदी या रूसी लोकेल में cp1251 जैसी। एक स्क्रिप्ट जो सर्वर पर ठीक चलती थी, दूसरे कंप्यूटर पर «Р•РґР°» जैसा कूड़ा छापती थी, या `UnicodeDecodeError` देती थी।

Python 3.15 में PEP 686 के अनुसार UTF-8 मोड डिफ़ॉल्ट है: `encoding` के बिना भी `open()` हर OS पर UTF-8 में पढ़ता और लिखता है। पुराना व्यवहार वापस पाने के लिए एनवायरनमेंट वेरिएबल `PYTHONUTF8=0` या फ़्लैग `-X utf8=0` है, और सिस्टम की एन्कोडिंग साफ़ माँगने के लिए `encoding="locale"`।

```
import sys
print(sys.flags.utf8_mode)   # Python 3.15 में 1

open("legacy.txt", encoding="locale")   # सिस्टम की एन्कोडिंग
open("old_excel.csv", encoding="cp1251")  # cp1251 में सहेजी फ़ाइल
```

इसका दूसरा पहलू: Excel या Windows स्क्रिप्ट से cp1251 में सहेजी पुरानी CSV अब UTF-8 समझकर पढ़ी जाएगी और `UnicodeDecodeError` देगी। इलाज: उसे `encoding="cp1251"` से पढ़ें और UTF-8 में दोबारा सहेजें। अच्छी आदत नहीं बदलती — `encoding` हमेशा साफ़ लिखें, तब कोड हर वर्ज़न पर एक जैसा चलेगा।

## Python में pathlib: पथ को ऑब्जेक्ट की तरह

पथों को स्ट्रिंग से जोड़ना (`"data" + "/" + name`) असुविधाजनक है और अलग-अलग OS पर टूटता है। मॉड्यूल `pathlib` में `Path` क्लास है, जहाँ पथ `/` ऑपरेटर से जुड़ते हैं, और ऑब्जेक्ट के पास साफ़ गुण होते हैं।

```
from pathlib import Path

data = Path("data")
csv_path = data / "expenses.csv"

print(csv_path.name)    # expenses.csv
print(csv_path.stem)    # expenses
print(csv_path.suffix)  # .csv
print(csv_path.parent)  # data
print(csv_path.exists())

data.mkdir(parents=True, exist_ok=True)
(data / "hello.txt").write_text("नमस्ते", encoding="utf-8")
print((data / "hello.txt").read_text(encoding="utf-8"))

for p in data.glob("*.csv"):
    print(p)
```

छोटी फ़ाइलों के लिए `read_text` और `write_text` `open` + `with` की जगह ले लेते हैं। `Path` ऑब्जेक्ट को साधारण `open`, `json` और `csv` — सभी स्वीकार करते हैं। स्क्रिप्ट की अपनी फ़ाइल के सापेक्ष पथ (मौजूदा फ़ोल्डर के सापेक्ष नहीं) के लिए लिखें: `Path(__file__).parent / "data"`।

Python 3.14 में `Path` पर `copy()` और `move()` मेथड आए, इसलिए साधारण कॉपी के लिए `shutil` की ज़रूरत नहीं रही। उसी वर्ज़न में स्टैंडर्ड लाइब्रेरी में Zstandard कंप्रेशन के लिए मॉड्यूल `compression.zstd` भी आया (PEP 784)।

## Python में JSON: load, dump, loads, dumps

JSON डेटा के आदान-प्रदान का टेक्स्ट फ़ॉर्मैट है: API इसे भेजते हैं, कॉन्फ़िग और रिपोर्ट इसमें रखे जाते हैं। मॉड्यूल `json` दो काम करता है: सीरियलाइज़ेशन (Python ऑब्जेक्ट → JSON टेक्स्ट) और डीसीरियलाइज़ेशन (टेक्स्ट → ऑब्जेक्ट)। फ़ंक्शन चार हैं, और उनमें गड़बड़ी आम सवाल है।

| फ़ंक्शन | क्या करता है |
| --- | --- |

| `json.dumps(obj)` | ऑब्जेक्ट → JSON स्ट्रिंग |

| `json.loads(s)` | JSON स्ट्रिंग → ऑब्जेक्ट |

| `json.dump(obj, f)` | ऑब्जेक्ट → खुली फ़ाइल में लिखना |

| `json.load(f)` | खुली फ़ाइल से JSON पढ़ना |

याद रखना आसान है: आख़िर का `s` string यानी स्ट्रिंग के लिए है; उसके बिना फ़ाइल के लिए।

### टाइप का मिलान

| Python | JSON |
| --- | --- |

| `dict` | ऑब्जेक्ट `{}` |

| `list`, `tuple` | ऐरे `[]` |

| `str` | स्ट्रिंग |

| `int`, `float` | संख्या |

| `True` / `False` | `true` / `false` |

| `None` | `null` |

टपल वापस पढ़ने पर सूची बन जाएगा, और सेट, तारीख़ें या `Decimal` मॉड्यूल नहीं जानता — वह `TypeError: Object of type ... is not JSON serializable` देगा।

### JSON फ़ाइल में सहेजना

```
import json
from pathlib import Path

report = {
    "month": "2026-10",
    "total": 15230.5,
    "categories": {"खाना": 8200, "यात्रा": 2100},
    "tags": ["घर", "काम"],
}

path = Path("data/report.json")
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("w", encoding="utf-8") as f:
    json.dump(report, f, ensure_ascii=False, indent=2)
```

`ensure_ascii=False` हिंदी अक्षरों को जैसे हैं वैसे रखता है। इसके बिना फ़ाइल में «खाना» की जगह `"खाना"` जैसा कोड आएगा — वह सही JSON है, पर इंसान के लिए पढ़ना असंभव। `indent=2` सुंदर इंडेंटेड फ़ॉर्मैट देता है।

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

```
with open("data/report.json", encoding="utf-8") as f:
    data = json.load(f)

print(data["total"])               # 15230.5
print(data["categories"]["खाना"])  # 8200
```

परिणाम एक साधारण डिक्शनरी या सूची है, जिसके साथ आप हमेशा की तरह काम करते हैं। अगर फ़ाइल JSON न हो या अधूरी हो, तो `json.JSONDecodeError` आएगा, जिसमें पंक्ति और स्थिति की जानकारी होती है — जब डेटा बाहर से आए, तो इसे पकड़ना चाहिए।

### JSON स्ट्रिंग का पार्सिंग और सुंदर आउटपुट

```
import json

raw = '{"name": "अनीता", "skills": ["python", "sql"], "active": true}'
user = json.loads(raw)
print(user["skills"][0])   # python

print(json.dumps(user, ensure_ascii=False, indent=2, sort_keys=True))
```

`sort_keys=True` कुंजियों को क्रम में छापता है — git में फ़ाइलों की तुलना के लिए सुविधाजनक। टर्मिनल से फ़ाइल को सुंदर बनाने के लिए मॉड्यूल का अंतर्निहित टूल है: `python -m json.tool data/report.json`।

HTTP API का जवाब भी JSON स्ट्रिंग होता है। लाइब्रेरी `requests` उसे `response.json()` से पार्स करती है, और भीतर वही `json.loads` चलता है।

### जाल: JSON की कुंजियाँ हमेशा स्ट्रिंग होती हैं

```
d = {1: "जनवरी", 2: "फ़रवरी"}
back = json.loads(json.dumps(d))
print(back == d)   # False
print(back)        # {'1': 'जनवरी', '2': 'फ़रवरी'}
# back[1] -> KeyError, इसके बजाय back["1"]

fixed = {int(k): v for k, v in back.items()}
```

JSON में ऑब्जेक्ट की कुंजियाँ सिर्फ़ स्ट्रिंग हो सकती हैं, इसलिए संख्यात्मक कुंजियाँ सीरियलाइज़ेशन के बाद स्ट्रिंग बन जाती हैं। पढ़ते समय उन्हें वापस बदलें।

### अपने प्रकार: तारीख़ें और Decimal

```
import json
from datetime import date

def default(obj):
    if isinstance(obj, date):
        return obj.isoformat()
    raise TypeError(f"{type(obj).__name__} को सीरियलाइज़ नहीं कर सकते")

print(json.dumps({"day": date(2026, 10, 1)}, default=default))
# {"day": "2026-10-01"}
```

`default` पैरामीटर में दिया फ़ंक्शन हर अज्ञात ऑब्जेक्ट के लिए बुलाया जाता है। जटिल मामलों के लिए `json.JSONEncoder` से उत्तराधिकार लेकर उसका `default` मेथड बदला जा सकता है।

### JSON ऐरे में एक तत्व जोड़ना

JSON को टेक्स्ट लॉग की तरह अंत में नहीं जोड़ा जा सकता: फ़ाइल को पढ़ना, बदलना और पूरा दोबारा लिखना होता है।

```
path = Path("data/items.json")
items = json.loads(path.read_text(encoding="utf-8")) if path.exists() else []
items.append({"id": len(items) + 1, "title": "नया"})
path.write_text(json.dumps(items, ensure_ascii=False, indent=2), encoding="utf-8")
```

अगर प्रविष्टियाँ बहुत हैं और लगातार जुड़ती हैं, तो JSON Lines फ़ॉर्मैट सुविधाजनक है: हर पंक्ति में एक JSON ऑब्जेक्ट, और फ़ाइल `"a"` मोड में खुलती है।

## Python में CSV: csv मॉड्यूल

CSV टेक्स्ट फ़ाइल में सारणी है: पंक्तियाँ रिकॉर्ड हैं, और मान कॉमा से अलग होते हैं। मॉड्यूल `csv` कोट, मानों के भीतर कॉमा और पंक्ति-ब्रेक ठीक से संभालता है — जो हाथ से लिखा `split(",")` नहीं करेगा।

```
import csv

with open("data/expenses.csv", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    total = 0.0
    for row in reader:
        total += float(row["amount"])
        print(row["date"], row["category"], row["amount"])
print("कुल:", total)
```

`csv.DictReader` हर पंक्ति को फ़ाइल के हेडर के अनुसार डिक्शनरी बनाता है। सारे मान स्ट्रिंग होते हैं: संख्याएँ और तारीख़ें ख़ुद बदलें (`float`, `int`, `date.fromisoformat`)। जिस फ़ाइल में विभाजक «;» है (रूसी Excel ऐसे ही सहेजता है), उसे `delimiter=";"` से पढ़ें।

```
rows = [
    {"date": "2026-10-01", "category": "खाना", "amount": 450},
    {"date": "2026-10-02", "category": "यात्रा", "amount": 60},
]
with open("data/out.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["date", "category", "amount"])
    writer.writeheader()
    writer.writerows(rows)
```

लिखते समय `newline=""` ज़रूरी है: उसके बिना Windows पर पंक्तियों के बीच खाली पंक्तियाँ आ जाएँगी। अगर फ़ाइल Excel में खोली जाएगी, तो `encoding="utf-8-sig"` लें — BOM चिह्न Excel को UTF-8 पहचानने में मदद करता है।

## CSV से JSON: पूरा उदाहरण

```
import csv
import json
from collections import defaultdict
from pathlib import Path

src = Path("data/expenses.csv")
dst = Path("data/report.json")

by_category = defaultdict(float)
with src.open(newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        by_category[row["category"]] += float(row["amount"])

report = {"total": sum(by_category.values()), "categories": dict(by_category)}
dst.write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
print(dst.read_text(encoding="utf-8"))
```

किसी भी रिपोर्ट-स्क्रिप्ट का मूल ढाँचा यही है: CSV से इनपुट, डिक्शनरी में एकत्रीकरण, JSON में आउटपुट।

## आम गलतियाँ

- `FileNotFoundError` — पथ सापेक्ष है और मौजूदा फ़ोल्डर से गिना जाता है, स्क्रिप्ट के फ़ोल्डर से नहीं। `Path(__file__).parent` लें।
- फ़ाइल खाली हो गई — `"w"` की जगह `"a"` लेना था।
- `UnicodeDecodeError` — फ़ाइल किसी और एन्कोडिंग में है; उसे साफ़ लिखें (`cp1251`, `utf-8-sig`)।
- `TypeError: Object of type set is not JSON serializable` — सूची में बदलें या `default` दें।
- JSON लोड करने के बाद `KeyError` — संख्यात्मक कुंजियाँ स्ट्रिंग बन चुकी हैं।
- अपनी फ़ाइल का नाम `json.py` या `csv.py` रख दिया — वह स्टैंडर्ड मॉड्यूल को ढक लेती है, और `import json` आपकी फ़ाइल को इम्पोर्ट करता है।

## निष्कर्ष

JSON के लिए Python की स्टैंडर्ड लाइब्रेरी काफ़ी है: फ़ाइलों के लिए `json.load`/`json.dump`, स्ट्रिंग के लिए `loads`/`dumps`, और पढ़ने योग्य आउटपुट के लिए `ensure_ascii=False` और `indent`। फ़ाइलें `with` से साफ़ एन्कोडिंग के साथ खोलें, पथ `pathlib` से बनाएँ, सारणी को `csv.DictReader` से पढ़ें। कोर्स में यह विषय व्यवहार में सिखाया जाता है: ख़र्च ट्रैकर CSV से ख़र्च पढ़ता है और रिपोर्ट JSON में सहेजता है।

## FAQ

**json.load और json.loads में क्या फ़र्क है?**

json.load खुले फ़ाइल-ऑब्जेक्ट से JSON पढ़ता है, और json.loads स्ट्रिंग को पार्स करता है। इसी तरह json.dump फ़ाइल में लिखता है, और json.dumps स्ट्रिंग लौटाता है।

**JSON में हिंदी अक्षर \u-कोड के बिना कैसे सहेजें?**

json.dump या json.dumps में ensure_ascii=False दें और फ़ाइल को encoding="utf-8" से खोलें।

**JSON के साथ काम करने के लिए कोई लाइब्रेरी इंस्टॉल करनी होगी?**

नहीं, मॉड्यूल json स्टैंडर्ड लाइब्रेरी में है; बस import json लिखना काफ़ी है।

**क्या JSON में तारीख़ या सेट रखा जा सकता है?**

सीधे नहीं। उन्हें बदलना होगा, जैसे तारीख़ को isoformat से ISO स्ट्रिंग में और सेट को सूची में, या default पैरामीटर में फ़ंक्शन देना होगा।

**बहुत बड़ा JSON, जो मेमोरी में नहीं आता, कैसे पढ़ें?**

मानक json.load पूरी फ़ाइल पढ़ता है; बड़े डेटा के लिए JSON Lines फ़ॉर्मैट रखें और json.loads से पंक्ति-दर-पंक्ति पार्स करें।


---
Source: Skillaria.Top (https://skillaria.top)
