File I/O (input/output) artinya membaca isi file dan menulis ke file. Variabel hilang begitu program selesai, sedangkan file tetap tersimpan di disk, jadi besok masih bisa dibuka lagi. Bayangin buku catatan penjualan Warung Kopi Pak Darto. Tiap kali dipakai, bukunya diambil dari rak dan dibuka dengan satu cara: cuma dibaca, dirobek semua halamannya lalu ditulis dari awal, ditulis di baris kosong paling akhir, atau buku baru yang ditolak kalau buku itu sudah ada. Di Python, cara membuka itu disebut mode, dan with memastikan bukunya dikembalikan ke rak.
🧪 Tebakan cepat:
penjualan.txtberisi tiga baris penjualan hari ini. Program membukanya dengan mode"w", lalu menulis satu barises jeruk,1. Sesudah itu, file-nya berisi berapa baris? Tebak dulu, jawabannya ada di bagian "Empat mode membuka file".
Membaca file
Isi penjualan.txt, di folder yang sama dengan warung.py:
kopi susu,3
teh manis,4
roti bakar,2
with open("penjualan.txt", "r", encoding="utf-8") as f:
for baris in f:
print(baris.strip())
kopi susu,3
teh manis,4
roti bakar,2
open(nama_file, mode, encoding=...)membuka file dan memberi objek file. Mode"r"artinya baca, dan itu bawaannya, jadi boleh gak ditulis.encoding="utf-8"memberi tahu cara huruf disimpan sebagai byte. Tanpa itu, Python memakai bawaan sistem operasi, yang di Windows bisa bukan UTF-8. Tulis selalu supaya hasilnya sama di semua komputer.with ... as f:adalah context manager dari pelajaran sebelumnya:fberisi file yang dibuka, dan file-nya ditutup otomatis begitu blok selesai.for baris in f:membaca satu baris per putaran. Tiap baris ikut membawa karakter baris baru di ujungnya,\n: baris pertama sebenarnya'kopi susu,3\n'..strip()membuangnya.
Tanpa .strip(), print(baris) mencetak \n milik baris itu ditambah baris baru dari print sendiri, jadi ada baris kosong di antaranya:
kopi susu,3
teh manis,4
roti bakar,2
Cara lain: f.read() membaca seluruh isi jadi satu string, 'kopi susu,3\nteh manis,4\nroti bakar,2\n', dan f.readlines() jadi list, ['kopi susu,3\n', 'teh manis,4\n', 'roti bakar,2\n'].
Empat mode membuka file
| Mode | Artinya | Kalau file-nya sudah ada | Kalau belum ada |
|---|---|---|---|
"r" |
baca | dibaca dari awal | FileNotFoundError: [Errno 2] No such file or directory: 'penjualan.txt' |
"w" |
tulis ulang | isinya dikosongkan dulu, lalu ditulis | dibuat |
"a" |
tambah di akhir (append) | isi lama tetap, tulisan baru di akhir | dibuat |
"x" |
bikin baru | FileExistsError: [Errno 17] File exists: 'penjualan.txt' |
dibuat |
Pak Darto mencatat satu gelas es jeruk dengan mode "a":
with open("penjualan.txt", "a", encoding="utf-8") as f:
f.write("es jeruk,1\n")
$ python3 warung.py
$ cat penjualan.txt
kopi susu,3
teh manis,4
roti bakar,2
es jeruk,1
(cat adalah perintah terminal yang menampilkan isi file; di Windows namanya type.) Dengan mode "w", perintah yang sama membuat cat cuma menampilkan es jeruk,1. Tiga baris lama hilang begitu file-nya dibuka, bahkan sebelum write jalan. Jadi jawaban tebakannya: satu baris. Mode gabungan seperti "r+" (baca dan tulis tanpa mengosongkan) juga ada, tapi jarang dibutuhkan.
f.write(teks)gak menambah baris baru sendiri.f.write("es jeruk,1")laluf.write("kopi susu,2")menghasilkan satu barises jeruk,1kopi susu,2. Tulis\nsendiri.writecuma menerima string:f.write(8000)gagal denganTypeError: write() argument must be str, not int. Ubah dulu denganstr(8000).
File tertutup setelah with
with open("penjualan.txt", encoding="utf-8") as f:
baris_pertama = f.readline()
print(baris_pertama.strip())
sisanya = f.read()
kopi susu,3
Traceback (most recent call last):
File "/home/darto/warung.py", line 4, in <module>
sisanya = f.read()
ValueError: I/O operation on closed file.
Variabel f masih ada, tapi file-nya sudah ditutup with di akhir blok (f.closed bernilai True). Semua yang membaca atau menulis file harus ada di dalam blok with. Menutup file itu penting: yang kamu tulis baru dijamin tersimpan ke disk saat file-nya ditutup.
CSV: file berisi tabel
CSV (comma-separated values) adalah tabel dalam teks biasa: satu baris satu data, kolomnya dipisah koma, dan baris pertama biasanya nama kolom. Isi penjualan.csv:
menu,jumlah,harga
kopi susu,3,15000
teh manis,4,5000
roti bakar,2,12000
import csv
total = 0
with open("penjualan.csv", encoding="utf-8", newline="") as f:
for baris in csv.DictReader(f):
print(baris)
total += int(baris["jumlah"]) * int(baris["harga"])
print(total)
{'menu': 'kopi susu', 'jumlah': '3', 'harga': '15000'}
{'menu': 'teh manis', 'jumlah': '4', 'harga': '5000'}
{'menu': 'roti bakar', 'jumlah': '2', 'harga': '12000'}
89000
csvadalah module bawaan Python.csv.DictReader(f)memakai baris pertama sebagai key, jadi tiap baris jadi dictionary.csv.reader(f)memberi tiap baris sebagai list biasa, baris judulnya ikut:['menu', 'jumlah', 'harga'], lalu['kopi susu', '3', '15000'], dan seterusnya.- Semua nilainya string.
baris["jumlah"] * 2memberi'33', bukan6. Ubah denganint()sebelum menghitung. Totalnya 89000, penjualan hari ini. newline=""dianjurkan dokumentasi Python untuk file CSV: modulecsvmengurus akhir barisnya sendiri.
📌 pathlib: alamat file sebagai objek
from pathlib import Path
p = Path("penjualan.txt")
print(p.exists()) # True
print(p.name, p.suffix) # penjualan.txt .txt
print(p.read_text(encoding="utf-8").splitlines()) # ['kopi susu,3', 'teh manis,4', 'roti bakar,2']
print(Path("laporan.txt").exists()) # False
Path dari module pathlib mewakili alamat file. exists() mengecek file-nya ada atau belum sebelum dibuka, dan read_text() membuka, membaca, lalu menutup file dalam satu panggilan. write_text(teks) kebalikannya, dan sama seperti mode "w", ia menimpa isi lama.
⚠️ Jebakan yang sering ketemu
- Mode
"w"dipakai untuk menambah. Isi lama langsung hilang. Untuk menambah di akhir, pakai"a". \nketinggalan atau terbawa.write()gak menambah baris baru, dan baris yang dibaca masih membawa\n. Tulis\nsendiri saat menulis,.strip()saat membaca.- Membaca di luar blok
with.ValueError: I/O operation on closed file.Pindahkan ke dalam blok. FileNotFoundErrorpadahal file-nya ada. Nama seperti"penjualan.txt"dicari di folder tempat kamu menjalankanpython3, bukan di folder skripnya. Jalankan dari folder yang sama, atau tulis alamat lengkapnya.
TL;DR: with open("penjualan.txt", "r", encoding="utf-8") as f: membuka file dan menutupnya otomatis di akhir blok; membaca sesudah blok jadi ValueError: I/O operation on closed file. Mode: "r" baca (file wajib ada, kalau gak FileNotFoundError), "w" mengosongkan lalu menulis, "a" menambah di akhir tanpa menghapus isi lama, "x" bikin file baru (kalau sudah ada FileExistsError). for baris in f: membaca per baris, dan tiap baris membawa \n, jadi pakai .strip(). write() cuma menerima string dan gak menambah \n. Tulis selalu encoding="utf-8". csv.DictReader membaca CSV jadi dictionary per baris, dan semua nilainya string, jadi int() dulu sebelum menghitung. Path("...").exists() mengecek file sebelum dibuka.