Sebagian besar data bertukar lewat berkas: hasil extract dari sistem sumber datang sebagai CSV, pertukaran dengan API memakai JSON, dan pipeline membaca serta menulis berkas itu setiap hari. Kesalahan kecil — encoding yang tidak disebut, mode "w" yang menimpa, atau newline yang diabaikan — menghasilkan berkas rusak yang baru terasa kemudian. Python menyediakan fungsi open(), class pathlib.Path, serta modul csv dan json untuk mengurus semuanya secara baku. Chapter ini membahas alurnya, lalu mengujinya lewat studi kasus: membaca CSV transaksi dan menulis hasilnya sebagai JSON.
Membuka Berkas: open() dan pathlib #
Fungsi open() menerima mode yang menentukan perlakuan terhadap berkas. Tabel berikut merangkum yang paling sering dipakai di pipeline:
| Mode | Perilaku |
|---|---|
"r" | baca; memicu FileNotFoundError bila berkas tidak ada |
"w" | tulis; isi lama ditimpa dari awal |
"a" | tambahkan di akhir; berkas dibuat bila belum ada |
"x" | tulis baru; memicu galat bila berkas sudah ada |
"b" / "t" | mode biner / teks (teks adalah bawaan) |
"+" | baca sekaligus tulis, mis. "r+" |
Untuk menyusun jalur, class pathlib.Path lebih aman daripada merangkai string manual. Cuplikan pertama kita akan memeriksa keberadaan transaksi.csv, jadi mari siapkan dulu berkas contoh itu — tiga baris penjualan yang dipakai lagi pada studi kasus. Metode write_text() menulis seluruh isi sekaligus dan membuat berkas bila belum ada:
from pathlib import Path
isi = (
"tanggal,kasir,produk,qty,harga\n"
"2026-01-15,budi,kopi lampung,2,24000\n"
"2026-01-15,siti,teh melati,3,15000\n"
"2026-01-16,dewi,gula aren,1,27000\n"
)
jumlah = Path("transaksi.csv").write_text(isi, encoding="utf-8")
print("Berkas dibuat:", Path("transaksi.csv").name)
print("Karakter ditulis:", jumlah)Output yang Dihasilkan:
Berkas dibuat: transaksi.csv
Karakter ditulis: 137Sekarang berkas itu benar-benar ada; cuplikan berikut memeriksanya:
from pathlib import Path
berkas = Path("transaksi.csv")
print(berkas)
print(berkas.parent)
print(berkas.stem, berkas.suffix)
print(berkas.exists())Output yang Dihasilkan:
transaksi.csv
.
transaksi .csv
TrueAtribut parent bernilai . karena berkas berada di direktori kerja; stem dan suffix memisahkan nama dari ekstensinya. Operator / menggabungkan jalur sesuai separator sistem operasi.
Modul csv: Baca dan Tulis Data Tabular #
Modul csv mengurus tanda kutip, koma di dalam nilai, dan baris baru — hal yang sering salah saat memotong string manual. csv.DictReader menghasilkan baris berupa dict sehingga kolom dipanggil dengan nama; csv.reader menghasilkan baris posisional; csv.writer menerima list per baris.
Satu aturan wajib: buka berkas CSV dengan newline="". Modul csv menulis baris baru dengan aturannya sendiri; tanpa newline="", sistem operasi yang menerjemahkan baris baru bisa menyisipkan baris kosong. Dokumentasi lengkapnya ada di https://docs.python.org/3/library/csv.html
.
Modul json: dump dan load #
Modul json punya dua pasang fungsi yang sering tertukar. json.dump(obj, f) menulis objek ke berkas terbuka, sedangkan json.dumps(obj) menghasilkan string; sebaliknya, json.load(f) membaca berkas menjadi objek Python, dan json.loads(teks) mengubah string menjadi objek.
Dua parameter penting: ensure_ascii=False menyimpan teks apa adanya alih-alih escape \uXXXX, dan indent=2 membuat berkas enak dibaca manusia. Rujukan resmi: https://docs.python.org/3/library/json.html
.
Studi Kasus: transaksi.csv menjadi transaksi.json #
Berkas sumber transaksi.csv berisi tiga baris berikut:
tanggal,kasir,produk,qty,harga
2026-01-15,budi,kopi lampung,2,24000
2026-01-15,siti,teh melati,3,15000
2026-01-16,dewi,gula aren,1,27000Skrip konversi.py membaca berkas tersebut, menulis JSON per baris, lalu meringkas per kasir ke CSV baru:
import csv
import json
from pathlib import Path
SUMBER = Path("transaksi.csv")
TUJUAN_JSON = Path("transaksi.json")
TUJUAN_CSV = Path("ringkas.csv")
# 1) Baca: newline="" wajib untuk modul csv, encoding utf-8
with SUMBER.open(mode="r", encoding="utf-8", newline="") as f:
pembaca = csv.DictReader(f)
barisan = list(pembaca)
# 2) Transform: nilai string diubah menjadi angka, tambah kolom total
bersih = []
for baris in barisan:
qty = int(baris["qty"])
harga = int(baris["harga"])
bersih.append({
"tanggal": baris["tanggal"],
"kasir": baris["kasir"].title(),
"produk": baris["produk"].title(),
"qty": qty,
"harga": harga,
"total": qty * harga,
})
# 3) Muat ke JSON: ensure_ascii=False agar teks tersimpan apa adanya
with TUJUAN_JSON.open(mode="w", encoding="utf-8") as f:
json.dump(bersih, f, ensure_ascii=False, indent=2)
# 4) Ringkas per kasir, tulis ke CSV baru
per_kasir = {}
for baris in bersih:
per_kasir[baris["kasir"]] = per_kasir.get(baris["kasir"], 0) + baris["total"]
with TUJUAN_CSV.open(mode="w", encoding="utf-8", newline="") as f:
penulis = csv.writer(f)
penulis.writerow(["kasir", "total"])
for kasir in sorted(per_kasir):
penulis.writerow([kasir, per_kasir[kasir]])
# 5) Baca kembali JSON hasil
with TUJUAN_JSON.open(mode="r", encoding="utf-8") as f:
hasil = json.load(f)
print("Baris dibaca :", len(bersih))
print("Total pendapatan:", sum(b["total"] for b in hasil))
print("--- transaksi.json ---")
print(TUJUAN_JSON.read_text(encoding="utf-8"))
print("--- ringkas.csv ---")
print(TUJUAN_CSV.read_text(encoding="utf-8"), end="")python3 konversi.pyOutput yang Dihasilkan:
Baris dibaca : 3
Total pendapatan: 120000
--- transaksi.json ---
[
{
"tanggal": "2026-01-15",
"kasir": "Budi",
"produk": "Kopi Lampung",
"qty": 2,
"harga": 24000,
"total": 48000
},
{
"tanggal": "2026-01-15",
"kasir": "Siti",
"produk": "Teh Melati",
"qty": 3,
"harga": 15000,
"total": 45000
},
{
"tanggal": "2026-01-16",
"kasir": "Dewi",
"produk": "Gula Aren",
"qty": 1,
"harga": 27000,
"total": 27000
}
]
--- ringkas.csv ---
kasir,total
Budi,48000
Dewi,27000
Siti,45000Mari kita telaah baris-per-baris kode di atas:
- Baris 10-12 (baca CSV):
newline=""menyerahkan pengaturan baris baru kepada modulcsv;DictReadermembaca baris pertama sebagai nama kolom danlist(pembaca)mengubah iterator menjadi list dict. - Baris 17-18 (
int(...)): semua nilai dari CSV bertipe string, jadi konversi keintwajib sebelumqty * hargadihitung. - Baris 29-30 (tulis JSON):
json.dumpmenulis ke berkas terbuka;ensure_ascii=Falsedanindent=2membuat hasil mudah dibaca manusia dan mesin. - Baris 37-41 (tulis CSV):
csv.writerdipasangkan dengannewline="";sorted(per_kasir)menjaga urutan kasir tetap stabil. - Baris 44-45 (baca kembali):
json.loadmengubah teks JSON menjadi list dict — data bolak-balik antar format tanpa kehilangan bentuk.
Alur di atas mulus karena datanya sengaja dibuat ramah. Kenyataannya, berkas sumber sering berisi baris rusak atau tidak ada sama sekali. Cara mengendalikannya dibahas di chapter berikutnya, Exception Handling.