Mwongozo

JSON katika Python: kusoma na kuandika faili, CSV, pathlib na usimbaji UTF-8

Imesasishwa: · Skillaria.Top

Kwa JSON katika Python kuna moduli ya kawaida json: json.load husoma data kutoka faili lililofunguliwa, json.dump huiandika kwenye faili, na json.loads na json.dumps hufanya hivyo hivyo kwa mifuatano. Faili hufunguliwa kwa with open(path, encoding="utf-8"), njia hujengwa kwa pathlib.Path, na jedwali husomwa kwa moduli ya csv.

Kufanya kazi na JSON katika Python hakuhitaji maktaba za nje: moduli json ipo katika maktaba ya kawaida na inageuza kamusi na orodha kuwa maandishi na kurudi tena. Karibu na hiyo mara nyingi unahitaji vitu vitatu zaidi: kazi open pamoja na muundo wa with, moduli pathlib kwa njia za faili, na moduli csv kwa majedwali. Hapa chini ni yote kwa mpangilio, pamoja na msimbo unaofanya kazi na mitego ambayo watu wengi hukwama nayo.

Kazi ya open katika Python: njia na usimbaji

Faili lolote la maandishi hufunguliwa kwa kazi iliyojengwa ndani open(path, mode, encoding=...). Inarudisha kitu cha faili chenye mbinu read, readline na write, na unaweza kukipitia kwa mzunguko mstari kwa mstari.

NjiaInafanya nini
"r"Kusoma (chaguo-msingi). Faili lisipokuwepo — FileNotFoundError
"w"Kuandika. Faili linaundwa au linafutwa mara tu linapofunguliwa
"a"Kuongeza mwishoni, yaliyomo yaliyopo hayaguswi
"x"Kuunda faili jipya; likiwepo tayari — FileExistsError
"b"Nyongeza ya njia: kufanya kazi na baiti ("rb", "wb")

Kwa nini with inahitajika

Faili linapaswa kufungwa: vinginevyo data inaweza isifike diskini, na mfumo unaendelea kushikilia kipini cha faili. Muundo wa with hufunga faili kiotomatiki — hata kama kulitokea kosa ndani ya kizuizi.

with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("Mstari wa kwanza\n")
    f.write("Mstari wa pili\n")

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

Kupitia faili kwa mzunguko husoma mstari mmoja kwa wakati na hakupakii faili lote kwenye kumbukumbu, kwa hiyo hata logi za gigabaiti zinaweza kuchakatwa hivyo. Mbinu f.read() itarudisha maudhui yote kama mfuatano mmoja, na f.readlines() — orodha ya mistari.

Jinsi ya kuandika mstari kwenye faili bila kufuta ya zamani

Kosa la kawaida la mwanzo ni kufungua faili kwa "w" ili "kuongeza" mstari. Hali "w" inafuta faili wakati wa kufunguliwa, kabla ya write ya kwanza. Ili kuongeza rekodi mwishoni tumia "a", na ili kuhakikisha hautaandika juu ya faili la mtu mwingine — "x".

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

Kumbuka kwamba write haiongezi mstari mpya yenyewe — "\n" inaandikwa waziwazi. Pia unaweza kutumia print(..., file=f): itaweka mwisho wa mstari kwa ajili yako.

Usimbaji UTF-8: kwa nini herufi zinaharibika

Kabla ya Python 3.15, kazi open() bila parameta encoding ilitumia usimbaji wa mfumo. Kwenye Linux na macOS hiyo ni UTF-8, lakini kwenye Windows inaweza kuwa cp1252 au nyingine. Skripti iliyofanya kazi vizuri kwenye seva, kwenye kompyuta ya mwenzako ilionyesha herufi zisizo sahihi (mojibake) au ilianguka kwa UnicodeDecodeError.

Katika Python 3.15, kwa PEP 686, hali ya UTF-8 imewashwa kwa chaguo-msingi: open() bila encoding inasoma na kuandika UTF-8 kwenye mifumo yote. Tabia ya zamani inaweza kurudishwa kwa kigezo cha mazingira PYTHONUTF8=0 au bendera -X utf8=0, na kuomba waziwazi usimbaji wa mfumo — encoding="locale".

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

open("legacy.txt", encoding="locale")     # usimbaji wa mfumo
open("old_excel.csv", encoding="cp1252")  # faili lililohifadhiwa kwa cp1252

Upande wa pili: CSV ya zamani kutoka Excel au skripti ya Windows, iliyohifadhiwa kwa cp1252, sasa itasomwa kama UTF-8 na kusababisha UnicodeDecodeError. Suluhisho: lisome kwa encoding="cp1252" kisha liandike upya kwa UTF-8. Kanuni nzuri haibadiliki — taja encoding waziwazi, basi msimbo unafanya kazi vivyo hivyo kwenye toleo lolote.

pathlib katika Python: njia kama vitu

Kuunganisha njia kwa mifuatano ("data" + "/" + name) ni ngumu na huvunjika kwenye mifumo tofauti. Moduli pathlib inatoa darasa Path, ambapo njia zinaunganishwa kwa opereta /, na kitu kina sifa zilizo wazi.

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

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

Mbinu read_text na write_text zinachukua nafasi ya mchanganyiko wa open + with kwa faili ndogo. Kitu cha Path kinaweza kupitishwa kwa open ya kawaida, kwa json na kwa csv — zote zinakipokea. Njia inayohusiana na skripti yenyewe, si folda ya sasa, hupatikana hivi: Path(__file__).parent / "data".

Katika Python 3.14 Path imepata mbinu copy() na move(), kwa hiyo kwa kunakili rahisi shutil haihitajiki tena. Katika toleo hilohilo maktaba ya kawaida imeongeza moduli compression.zstd kwa mbano ya Zstandard (PEP 784).

JSON katika Python: load, dump, loads, dumps

JSON ni muundo wa maandishi wa kubadilishana data: API hutuma data kwa JSON, na mipangilio na ripoti huhifadhiwa humo. Moduli json inafanya shughuli mbili: serialization (kitu cha Python → maandishi ya JSON) na deserialization (maandishi → kitu). Mbinu ni nne, na kuchanganyikiwa kati yake ni swali la kawaida.

KaziInafanya nini
json.dumps(obj)Kitu → mfuatano wa JSON
json.loads(s)Mfuatano wa JSON → kitu
json.dump(obj, f)Kitu → kuandika kwenye faili lililofunguliwa
json.load(f)Kusoma JSON kutoka faili lililofunguliwa

Ni rahisi kukumbuka: herufi s mwishoni inamaanisha string — kazi na mfuatano; bila hiyo — kazi na faili.

Ulinganifu wa aina

PythonJSON
dictkitu {}
list, tuplesafu []
strmfuatano
int, floatnamba
True / Falsetrue / false
Nonenull

Tuple ikisomwa tena itakuwa orodha, lakini seti, tarehe na Decimal moduli haizijui na itatoa TypeError: Object of type ... is not JSON serializable.

Jinsi ya kuhifadhi JSON kwenye faili

import json
from pathlib import Path

report = {
    "month": "2026-10",
    "total": 15230.5,
    "categories": {"chakula": 8200, "usafiri": 2100},
    "tags": ["nyumbani", "kazi"],
}

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)

Parameta ensure_ascii=False huhifadhi herufi za lugha yako kama zilivyo. Bila hiyo, badala ya "chakula" faili litakuwa na "c..." — JSON sahihi, lakini ni vigumu kwa binadamu kuisoma. indent=2 hupanga muundo kwa mikunjo.

Jinsi ya kusoma JSON kutoka faili

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

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

Matokeo ni kamusi au orodha ya kawaida, na unaifanyia kazi kwa zana za kawaida. Faili lisilo JSON au lililokatika litasababisha json.JSONDecodeError yenye namba ya mstari na nafasi — inafaa kuikamata pale data inapotoka nje.

Kuchambua mfuatano wa JSON na uchapishaji mzuri

import json

raw = '{"name": "Amina", "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 hupanga funguo wakati wa kutoa matokeo — ni muhimu ili kulinganisha faili kwenye git. Kwa kupanga faili haraka kutoka terminal kuna zana iliyojengwa ndani: python -m json.tool data/report.json.

Jibu la HTTP API pia ni mfuatano wa JSON. Maktaba ya requests huichambua kwa mbinu response.json(), na ndani yake ni json.loads ile ile.

Mtego: funguo za JSON daima ni mifuatano

d = {1: "januari", 2: "februari"}
back = json.loads(json.dumps(d))
print(back == d)   # False
print(back)        # {'1': 'januari', '2': 'februari'}
# back[1] -> KeyError, inahitajika back["1"]

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

Katika JSON funguo za kitu zinaweza kuwa mifuatano tu, kwa hiyo funguo za namba baada ya mzunguko wa serialization zinageuka kuwa mifuatano. Zirejeshe kuwa namba unaposoma.

Aina zako mwenyewe: tarehe na Decimal

import json
from datetime import date

def default(obj):
    if isinstance(obj, date):
        return obj.isoformat()
    raise TypeError(f"siwezi kuweka {type(obj).__name__} kwenye mfuatano")

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

Kazi iliyo kwenye parameta default huitwa kwa kila kitu kisichojulikana. Kwa visa tata unaweza kurithi kutoka json.JSONEncoder na kubadilisha mbinu default.

Jinsi ya kuongeza kipengele kwenye safu ya JSON

JSON haiwezi kuongezwa mwishoni kama logi ya maandishi: faili linapaswa kusomwa, kubadilishwa na kuandikwa upya kwa ujumla.

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

Ikiwa rekodi ni nyingi na zinaongezwa kila mara, muundo wa JSON Lines ni rahisi zaidi: kitu kimoja cha JSON kwa mstari, na faili linafunguliwa kwa hali "a".

CSV katika Python: moduli csv

CSV ni jedwali katika faili la maandishi: mistari ni rekodi, thamani zimetenganishwa kwa koma. Moduli csv inashughulikia nukuu, koma ndani ya thamani na mivunjo ya mistari kwa usahihi, jambo ambalo split(",") ya kawaida haliwezi kufanya.

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("Jumla:", total)

csv.DictReader hugeuza kila mstari kuwa kamusi kwa kichwa cha faili. Thamani zote ni mifuatano: namba na tarehe zibadilishwe mwenyewe (float, int, date.fromisoformat). Faili lenye kitenganishi ";" (ambacho Excel ya Ulaya huhifadhi) husomwa kwa parameta delimiter=";".

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

Wakati wa kuandika newline="" ni lazima: bila hiyo, kwenye Windows, mistari tupu itaonekana kati ya mistari. Ikiwa faili litafunguliwa kwenye Excel, tumia encoding="utf-8-sig" — alama ya BOM inasaidia Excel kutambua UTF-8.

Kutoka CSV hadi JSON: mfano kamili

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

Huu ndio msingi wa skripti yoyote ya ripoti: ingizo kutoka CSV, mkusanyiko kwenye kamusi, na pato kwa JSON.

Makosa ya kawaida

  • FileNotFoundError — njia ni ya jamaa na inahesabiwa kutoka folda ya kuendesha, si kutoka skripti. Tumia Path(__file__).parent.
  • Faili limefutwa — lilifunguliwa kwa "w" badala ya "a".
  • UnicodeDecodeError — faili lina usimbaji mwingine; itaje waziwazi (cp1252, utf-8-sig).
  • TypeError: Object of type set is not JSON serializable — badilisha kuwa orodha au pitisha default.
  • KeyError baada ya kupakia JSON — funguo za namba zimekuwa mifuatano.
  • Faili lako limeitwa json.py au csv.py — linafunika moduli ya kawaida, na import json itaingiza faili lako.

Hitimisho

Kwa JSON katika Python maktaba ya kawaida inatosha: json.load/json.dump kwa faili, loads/dumps kwa mifuatano, ensure_ascii=False na indent kwa matokeo yanayosomeka. Fungua faili kwa with pamoja na usimbaji ulio wazi, jenga njia kwa pathlib, na soma majedwali kwa csv.DictReader. Katika kozi ya Python mada hii inafundishwa kwa vitendo: kifuatiliaji cha matumizi kinasoma matumizi kutoka CSV na kuhifadhi ripoti kwenye JSON.

Maswali ya mara kwa mara

json.load inatofautianaje na json.loads?

json.load husoma JSON kutoka kitu cha faili kilichofunguliwa, na json.loads huchambua mfuatano. Vivyo hivyo json.dump huandika kwenye faili, na json.dumps hurudisha mfuatano.

Ninawezaje kuhifadhi herufi za lugha yangu kwenye JSON bila mfuatano wa \u?

Pitisha ensure_ascii=False kwenye json.dump au json.dumps, na ufungue faili kwa encoding="utf-8".

Je, ni lazima kusakinisha maktaba ili kufanya kazi na JSON katika Python?

Hapana, moduli json imejengwa ndani ya maktaba ya kawaida; inatosha kuandika import json.

Je, naweza kuhifadhi tarehe au seti kwenye JSON?

Moja kwa moja hapana: zinahitaji kubadilishwa, kwa mfano tarehe kuwa mfuatano wa ISO kwa isoformat, na seti kuwa orodha, au kupitisha kazi kwenye parameta default.

Ninawezaje kusoma JSON kubwa isiyoingia kwenye kumbukumbu?

json.load ya kawaida inasoma faili lote; kwa data kubwa hifadhi katika muundo wa JSON Lines na uchambue kwa mstari kwa json.loads.

Jifunze mada hii kwa video

Mada hii inafundishwa kwa kina pamoja na mazoezi katika kozi “Python 3.15: от новичка до профи”.

Nenda kwenye kozi