# JSON sa Python: pagbasa at pagsulat ng file, CSV, pathlib, at UTF-8 encoding

URL: https://skillaria.top/tl/guides/python/json-python-file

Para sa JSON sa Python, may built-in na module na json: ang json.load ay nagbabasa ng datos mula sa bukas na file, ang json.dump ay nagsusulat dito, at ang json.loads at json.dumps ay gumagawa ng parehong bagay sa string. Binubuksan ang file gamit ang with open(path, encoding="utf-8"), ginagawa ang mga path gamit ang pathlib.Path, at ang mga talahanayan ay binabasa gamit ang module na csv.

Hindi kailangan ng third-party na library para sa JSON sa Python: nasa standard library ang module na `json` at ginagawang teksto ang mga dictionary at list, at pabalik. Kasama nito, halos palaging kailangan ang tatlong bagay: ang function na `open` kasama ng `with`, ang module na `pathlib` para sa mga path, at ang module na `csv` para sa mga talahanayan. Sa ibaba, ang lahat ng ito nang sunod-sunod, may gumaganang code at mga bitag na madalas tamaan.

## Ang function na open sa Python: mga mode at encoding

Binubuksan ang anumang text file gamit ang built-in na function na `open(path, mode, encoding=...)`. Nagbabalik ito ng file object na may mga method na `read`, `readline`, at `write`, at maaari itong daanan linya-linya sa loop.

| Mode | Ginagawa |
| --- | --- |

| `"r"` | Pagbabasa (default). Kapag walang file — `FileNotFoundError` |

| `"w"` | Pagsulat. Ginagawa ang file o **binubura ang laman agad pagbukas** |

| `"a"` | Idaragdag sa dulo, hindi ginagalaw ang umiiral na laman |

| `"x"` | Gumawa ng bagong file; kapag mayroon na — `FileExistsError` |

| `"b"` | Dagdag sa mode: pagtatrabaho sa bytes (`"rb"`, `"wb"`) |

### Bakit kailangan ang with

Kailangang isara ang file: kung hindi, maaaring hindi maisulat sa disk ang datos, at nananatiling okupado ang file descriptor ng sistema. Awtomatikong isinasara ng `with` ang file — kahit may error sa loob ng block.

```
with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("Unang linya\n")
    f.write("Ikalawang linya\n")

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

Ang pagdaan sa file gamit ang loop ay bumabasa nang isang linya sa bawat pagkakataon, at hindi ito ikinakarga nang buo sa memorya — kaya kayang iproseso ng ganitong paraan kahit gigabyte na log. Ibinabalik ng `f.read()` ang buong laman bilang iisang string, at ng `f.readlines()` ang listahan ng mga linya.

### Paano magsulat ng linya sa file nang hindi nabubura ang luma

Pinakakaraniwang pagkakamali ng baguhan ang pagbukas ng file sa mode na `"w"` para "magdagdag" ng linya. Nililinis ng mode na `"w"` ang file sa sandali ng pagbukas, bago pa ang unang `write`. Para magdagdag sa dulo, gamitin ang `"a"`, at para tiyak na hindi ma-overwrite ang file ng iba, gamitin ang `"x"`.

```
with open("log.txt", "a", encoding="utf-8") as f:
    f.write("bagong entry\n")
```

Tandaan na hindi awtomatikong nagdaragdag ng line break ang `write` — ang `"\n"` ay dapat isulat nang tahasan. Maaari ring gamitin ang `print(..., file=f)`, dahil siya na ang maglalagay ng line break.

## Encoding na UTF-8: bakit lumalabas ang mga sirang karakter

Bago ang Python 3.15, kinukuha ng `open()` na walang parameter na `encoding` ang encoding ng sistema. Sa Linux at macOS, UTF-8 ito; sa Windows na may Russian locale, cp1251. Ang script na maayos na tumatakbo sa server ay naglalabas ng "Р•РґР°" imbes na "Еда" sa laptop ng kasamahan, o bumabagsak na may `UnicodeDecodeError`.

Sa Python 3.15, ayon sa PEP 686, naka-enable bilang default ang UTF-8 mode: ang `open()` na walang `encoding` ay nagbabasa at nagsusulat ng UTF-8 sa lahat ng OS. Maibabalik ang lumang kilos gamit ang environment variable na `PYTHONUTF8=0` o flag na `-X utf8=0`, at para tahasang hilingin ang encoding ng sistema, gamitin ang `encoding="locale"`.

```
import sys
print(sys.flags.utf8_mode)   # 1 sa Python 3.15

open("legacy.txt", encoding="locale")   # encoding ng sistema
open("old_excel.csv", encoding="cp1251")  # file na naka-save sa cp1251
```

Ang kabilang panig: ang lumang CSV mula sa Excel o script sa Windows na naka-save sa cp1251 ay babasahin na ngayon bilang UTF-8 at magdudulot ng `UnicodeDecodeError`. Ang lunas: basahin gamit ang `encoding="cp1251"` at i-save muli sa UTF-8. Ang mabuting gawi ay nananatili — tahasang ilagay ang `encoding`, para pareho ang kilos ng code sa anumang bersyon.

## pathlib sa Python: mga path bilang object

Nakakainis ang pagdudugtong ng path gamit ang string (`"data" + "/" + name`), at sumisira ito sa iba't ibang OS. Nagbibigay ang module na `pathlib` ng klaseng `Path`, kung saan pinagdurugtong ang mga path gamit ang operator na `/`, at may malinaw na mga property ang object.

```
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("Kumusta", encoding="utf-8")
print((data / "hello.txt").read_text(encoding="utf-8"))

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

Pinapalitan ng mga method na `read_text` at `write_text` ang kombinasyon ng `open` at `with` para sa maliliit na file. Maaaring ipasa ang object na `Path` sa karaniwang `open`, sa `json`, at sa `csv` — tinatanggap ito ng lahat. Ang path na kaugnay ng mismong script, at hindi ng kasalukuyang folder, ay nakukuha sa ganitong paraan: `Path(__file__).parent / "data"`.

Sa Python 3.14, nagkaroon ng mga method na `copy()` at `move()` ang `Path`, kaya hindi na kailangan ang `shutil` para sa simpleng pagkopya. Sa parehong bersyon, idinagdag sa standard library ang module na `compression.zstd` para sa Zstandard compression (PEP 784).

## JSON sa Python: load, dump, loads, dumps

Ang JSON ay text na format para sa pagpapalitan ng datos: ibinibigay ito ng mga API, at ginagamit ito sa pag-iimbak ng config at ulat. May dalawang operasyon ang module na `json`: serialization (Python object → teksto ng JSON) at deserialization (teksto → object). Apat ang function, at madalas itanong ang pagkalito sa pagitan nila.

| Function | Ginagawa |
| --- | --- |

| `json.dumps(obj)` | Object → string ng JSON |

| `json.loads(s)` | String ng JSON → object |

| `json.dump(obj, f)` | Object → isulat sa bukas na file |

| `json.load(f)` | Basahin ang JSON mula sa bukas na file |

Madaling tandaan: ang letrang `s` sa dulo ay nangangahulugang string — pagtatrabaho sa string; kung wala ito, sa file.

### Pagkakatugma ng mga uri

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

| `dict` | object `{}` |

| `list`, `tuple` | array `[]` |

| `str` | string |

| `int`, `float` | numero |

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

| `None` | `null` |

Ang tuple ay magiging listahan pagkatapos ng pabalik na pagbabasa, at ang set, petsa, at `Decimal` ay hindi kilala ng module — magbibigay ito ng `TypeError: Object of type ... is not JSON serializable`.

### Paano mag-save ng JSON sa file

```
import json
from pathlib import Path

report = {
    "month": "2026-10",
    "total": 15230.5,
    "categories": {"pagkain": 8200, "transportasyon": 2100},
    "tags": ["bahay", "trabaho"],
}

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)
```

Pinapanatili ng parameter na `ensure_ascii=False` ang mga karakter na Cyrillic (o anumang di-ASCII) gaya ng mga ito. Kung wala ito, lalabas sa file ang `"\u0435\u0434\u0430"` imbes na ang salitang "еда" — tamang JSON pa rin ito, pero hindi na ito mabasa ng tao. Ang `indent=2` ay gumagawa ng magandang pag-format na may indentation.

### Paano magbasa ng JSON mula sa file

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

print(data["total"])               # 15230.5
print(data["categories"]["pagkain"])   # 8200
```

Ang resulta ay ordinaryong dictionary o listahan, at gagamitin ito sa mga karaniwang paraan. Kung hindi JSON ang file o putol ito, magkakaroon ng exception na `json.JSONDecodeError` na may numero ng linya at posisyon — dapat itong hulihin kapag galing sa labas ang datos.

### Pag-parse ng JSON string at magandang output

```
import json

raw = '{"name": "Anna", "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))
```

Inaayos ng `sort_keys=True` ang mga key sa output — kapaki-pakinabang para maihambing ang mga file sa git. Para mabilis na i-format ang file mula sa terminal, may built-in na utility: `python -m json.tool data/report.json`.

Ang sagot ng HTTP API ay string din ng JSON. Pinoproseso ito ng library na `requests` gamit ang method na `response.json()`, at sa ilalim nito, ang parehong `json.loads`.

### Bitag: laging string ang mga key ng JSON

```
d = {1: "enero", 2: "pebrero"}
back = json.loads(json.dumps(d))
print(back == d)   # False
print(back)        # {'1': 'enero', '2': 'pebrero'}
# back[1] -> KeyError, kailangan ang back["1"]

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

Sa JSON, string lang ang puwedeng maging key ng object, kaya nagiging string ang mga numerong key pagkatapos ng serialization. Ibalik ang mga ito sa tamang uri kapag binabasa.

### Sariling mga uri: petsa at Decimal

```
import json
from datetime import date

def default(obj):
    if isinstance(obj, date):
        return obj.isoformat()
    raise TypeError(f"hindi kayang i-serialize ang {type(obj).__name__}")

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

Tinatawag ang function sa parameter na `default` para sa bawat hindi kilalang object. Para sa mas kumplikadong kaso, maaaring magmana mula sa `json.JSONEncoder` at i-override ang method na `default`.

### Paano magdagdag ng elemento sa JSON array

Hindi maaaring idagdag sa dulo ang JSON gaya ng text na log: kailangang basahin ang file, baguhin, at isulat nang buo.

```
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": "bago"})
path.write_text(json.dumps(items, ensure_ascii=False, indent=2), encoding="utf-8")
```

Kapag maraming record at palagiang dinadagdagan, mas maginhawa ang format na JSON Lines: isang JSON object bawat linya, at ang file ay binubuksan sa mode na `"a"`.

## CSV sa Python: module na csv

Ang CSV ay talahanayan sa text file: bawat linya ay isang rekord, at pinaghihiwalay ng kuwit ang mga halaga. Tama ang paghawak ng module na `csv` sa mga quote, kuwit sa loob ng halaga, at line break — hindi ito magagawa ng manual na `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("Kabuuan:", total)
```

Ginagawang dictionary ng `csv.DictReader` ang bawat linya ayon sa header ng file. Lahat ng halaga ay string: kailangan mong i-convert ang mga numero at petsa nang mag-isa (`float`, `int`, `date.fromisoformat`). Ang file na may separator na ";" (ganito mag-save ang Excel sa Russian locale) ay binabasa gamit ang parameter na `delimiter=";"`.

```
rows = [
    {"date": "2026-10-01", "category": "pagkain", "amount": 450},
    {"date": "2026-10-02", "category": "transportasyon", "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)
```

Kapag nagsusulat, kailangan ang `newline=""`: kung wala, lalabas ang mga walang lamang linya sa pagitan sa Windows. Kung bubuksan ang file sa Excel, gamitin ang `encoding="utf-8-sig"` — tumutulong ang BOM marker para makilala ng Excel ang UTF-8.

## Mula CSV papuntang JSON: buong halimbawa

```
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"))
```

Ito ang sentro ng anumang script ng ulat: pasok sa CSV, pagsasama-sama sa dictionary, labas sa JSON.

## Karaniwang pagkakamali

- `FileNotFoundError` — kamag-anak ang path at kinukuha mula sa folder kung saan pinatakbo, hindi mula sa script. Gamitin ang `Path(__file__).parent`.
- Nabura ang file — binuksan sa `"w"` sa halip na `"a"`.
- `UnicodeDecodeError` — ibang encoding ang file; tahasang ilagay ito (`cp1251`, `utf-8-sig`).
- `TypeError: Object of type set is not JSON serializable` — i-convert sa listahan o magpasa ng `default`.
- `KeyError` pagkatapos mag-load ng JSON — naging string ang mga numerong key.
- Pinangalanan ang sariling file na `json.py` o `csv.py` — tinatakpan nito ang standard module, at ang `import json` ay ina-import ang sarili mong file.

## Buod

Para sa JSON sa Python, sapat na ang standard library: `json.load`/`json.dump` para sa file, `loads`/`dumps` para sa string, at `ensure_ascii=False` at `indent` para sa madaling basahin na output. Buksan ang file gamit ang `with` na may tahasang encoding, buuin ang path gamit ang `pathlib`, at basahin ang talahanayan gamit ang `csv.DictReader`. Tinalakay ang paksang ito nang praktikal sa kurso ng Python: binabasa ng tagasubaybay ng gastos ang mga gastos mula sa CSV at isinusulat ang ulat sa JSON.

## FAQ

**Ano ang pagkakaiba ng json.load at json.loads?**

Binabasa ng json.load ang JSON mula sa bukas na file object, samantalang sinusuri ng json.loads ang string. Gayundin, isinusulat ng json.dump sa file, at ibinabalik ng json.dumps ang string.

**Paano i-save ang mga letrang Cyrillic sa JSON nang walang \u-sequence?**

Ipasa ang ensure_ascii=False sa json.dump o json.dumps, at buksan ang file na may encoding="utf-8".

**Kailangan bang mag-install ng library para sa JSON sa Python?**

Hindi, nasa standard library ang module na json; sapat na ang import json.

**Maaari bang maglagay ng petsa o set sa JSON?**

Hindi direkta: kailangang i-convert muna, halimbawa ang petsa sa ISO string gamit ang isoformat, at ang set sa listahan; o magpasa ng function sa parameter na default.

**Paano basahin ang malaking JSON na hindi kasya sa memorya?**

Binabasa ng karaniwang json.load ang buong file. Para sa malalaking volume, itago ang datos sa format na JSON Lines at iproseso ito linya-linya gamit ang json.loads.


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