Python Files, Errors, dan Modules: Membuat Script yang Lebih Rapi
Setelah paham function dan struktur data, kamu sudah bisa menulis logic yang cukup rapi. Tantangan berikutnya adalah membuat script yang berinteraksi dengan dunia luar: membaca file, menulis hasil, menangani error, dan memecah kode ke beberapa file.
Ini penting karena banyak pekerjaan Python sehari-hari berbentuk script kecil: mengolah CSV, membersihkan data, membaca konfigurasi, membuat laporan, atau menjalankan automation sederhana.
Cara berpikirnya adalah memisahkan tiga hal: sumber data, proses, dan respons saat proses gagal. File menjadi sumber data atau tempat hasil disimpan. Function menjadi tempat proses. try dan except menentukan respons yang masuk akal ketika kondisi di luar dugaan terjadi. Module lalu membantu mengelompokkan bagian-bagian tersebut agar tidak menumpuk di satu file.
Kenapa file penting?
Kalau data hanya hidup di variabel, data itu hilang saat program selesai. File membuat data bisa disimpan dan dibaca lagi.
Contoh kasus:
- Membaca daftar transaksi dari file.
- Menyimpan hasil laporan ke file baru.
- Membaca konfigurasi aplikasi.
- Menulis log sederhana saat script berjalan.
Python menyediakan fungsi bawaan open() untuk bekerja dengan file.
Membaca file dengan with open
Cara aman membaca file adalah menggunakan with open(...).
# File: 01-read-text-file.py
with open("notes.txt", "r", encoding="utf-8") as file:
content = file.read()
print(content)
"r" berarti read mode. encoding="utf-8" membantu file teks dibaca konsisten, terutama jika ada karakter non-ASCII.
Blok with memastikan file ditutup otomatis setelah selesai. Ini kebiasaan kecil yang bagus untuk dibangun sejak awal.
Membaca per baris
Kalau file berisi banyak baris, kamu bisa membaca semuanya sebagai list:
# File: 02-read-lines.py
with open("notes.txt", "r", encoding="utf-8") as file:
lines = file.readlines()
for line in lines:
print(line.strip())
strip() menghapus spasi atau newline di awal dan akhir string.
Untuk file besar, lebih hemat memproses langsung baris per baris:
# File: 03-stream-lines.py
with open("notes.txt", "r", encoding="utf-8") as file:
for line in file:
print(line.strip())
Menulis file
Gunakan mode "w" untuk menulis file.
# File: 04-write-file.py
report = "Total: 150000\n"
with open("report.txt", "w", encoding="utf-8") as file:
file.write(report)
Mode "w" akan menimpa isi file jika file sudah ada. Jika kamu ingin menambahkan isi di akhir file, gunakan mode "a":
# File: 05-append-log.py
with open("app.log", "a", encoding="utf-8") as file:
file.write("Script started\n")
Path dan working directory
Kesalahan yang sering muncul adalah file tidak ditemukan padahal file sebenarnya ada. Biasanya penyebabnya adalah working directory.
Saat kamu menulis:
# File: 06-open-relative-file.py
open("notes.txt")
Python mencari notes.txt dari folder tempat command dijalankan, bukan selalu dari lokasi file Python.
Untuk script kecil, jalankan command dari folder project. Untuk project yang lebih rapi, kamu bisa memakai pathlib:
# File: 07-pathlib-path.py
from pathlib import Path
base_dir = Path(__file__).parent
notes_path = base_dir / "notes.txt"
print(notes_path)
pathlib membuat operasi path lebih jelas dibanding menyambung string manual.
Path relatif bergantung pada folder tempat command dijalankan. Path berbasis __file__ bergantung pada lokasi script, sehingga lebih stabil saat script dijalankan dari folder lain. Bedakan keduanya: untuk file input yang memang dipilih user, path relatif bisa cukup; untuk asset milik project, pathlib berbasis lokasi file biasanya lebih aman.
Error yang sering muncul
Saat bekerja dengan file dan input, beberapa error umum adalah:
FileNotFoundError: file tidak ada di path yang dicari.ValueError: konversi gagal, misalnyaint("abc").PermissionError: program tidak punya izin membaca atau menulis file.- Parsing error: format data tidak sesuai ekspektasi.
Program yang baik tidak selalu mencegah semua error. Tapi program yang baik memberi respons yang jelas saat error terjadi.
try dan except
Gunakan try dan except untuk menangani error yang memang mungkin terjadi.
# File: 08-read-lines-fallback.py
def read_lines(path):
try:
with open(path, "r", encoding="utf-8") as file:
return file.readlines()
except FileNotFoundError:
return []
lines = read_lines("notes.txt")
print(f"Total lines: {len(lines)}")
Di sini, jika file belum ada, function mengembalikan list kosong. Untuk beberapa kasus ini masuk akal. Untuk kasus lain, mungkin lebih baik menampilkan pesan error dan menghentikan program.
except yang spesifik
Hindari except: tanpa tipe error.
# File: 09-bare-except-bug.py
try:
amount = int(input("Amount: "))
except:
amount = 0
Kode seperti ini menangkap terlalu banyak hal. Lebih baik spesifik:
# File: 10-specific-except.py
try:
amount = int(input("Amount: "))
except ValueError:
print("Amount must be a number")
amount = 0
Error yang spesifik membuat debugging lebih mudah.
Jangan memakai exception untuk menggantikan conditional biasa. Gunakan if ketika kondisi bisa diperiksa dengan normal, dan gunakan try ketika operasi memang dapat gagal, seperti membuka file atau mengubah teks menjadi angka. Saat menangkap error, pilih respons yang tepat: minta input ulang, gunakan nilai fallback, atau teruskan error dengan pesan yang jelas.
else dan finally
else berjalan jika tidak ada error. finally berjalan apa pun hasilnya.
# File: 11-try-else-finally.py
try:
amount = int(input("Amount: "))
except ValueError:
print("Invalid amount")
else:
print(f"Saved amount: {amount}")
finally:
print("Done")
Kamu tidak harus memakai else dan finally setiap saat, tapi penting tahu kapan mereka berguna.
Membuat module sendiri
Saat file Python mulai panjang, pisahkan kode ke module. Module adalah file Python yang bisa di-import.
Misalnya buat file calculator.py:
# File: 12-calculator-module.py
def add(a, b):
return a + b
def multiply(a, b):
return a * b
Lalu di main.py:
# File: 13-import-module.py
from calculator import add, multiply
print(add(2, 3))
print(multiply(4, 5))
Dengan module, kode utama bisa fokus pada alur program, sementara detail logic dipisah ke file lain.
Hindari side effect saat import
Kode di level paling atas sebuah file akan berjalan saat file di-import. Karena itu, hindari menjalankan program utama langsung di module yang akan di-import.
Gunakan pola ini:
# File: 14-main-guard.py
def main():
print("Run app")
if __name__ == "__main__":
main()
Dengan pola tersebut, main() hanya berjalan saat file dieksekusi langsung, bukan saat di-import.
Package sederhana
Package adalah folder berisi module Python. Biasanya folder itu punya file __init__.py.
expense_app/
__init__.py
storage.py
calculator.py
main.py
Contoh import:
# File: 15-package-imports.py
from expense_app.storage import read_expenses
from expense_app.calculator import calculate_total
Kamu belum perlu masuk terlalu dalam ke packaging. Untuk tahap ini, cukup paham bahwa folder bisa dipakai untuk mengelompokkan module.
Mini project: total transaksi dari file
Buat file transactions.txt:
Coffee,25000
Lunch,50000
Book,120000
Lalu buat main.py:
# File: 16-transaction-total.py
def read_transactions(path):
transactions = []
try:
with open(path, "r", encoding="utf-8") as file:
for line in file:
title, amount_text = line.strip().split(",")
transactions.append({
"title": title,
"amount": int(amount_text),
})
except FileNotFoundError:
print("Transaction file not found")
return transactions
def calculate_total(transactions):
return sum(transaction["amount"] for transaction in transactions)
transactions = read_transactions("transactions.txt")
total = calculate_total(transactions)
print(f"Total: {total}")
Script ini sudah memakai file, list, dictionary, function, dan error handling dasar.
Kesalahan umum
Kesalahan pertama adalah hardcode path absolut seperti /Users/name/Desktop/file.txt. Path seperti ini sulit dipakai ulang di komputer lain.
Kesalahan kedua adalah menangkap semua error dengan bare except. Ini bisa menyembunyikan bug asli.
Kesalahan ketiga adalah membuat module yang langsung menjalankan banyak proses saat di-import. Pisahkan function dan gunakan if __name__ == "__main__":.
Latihan mini
Coba buat:
- Script yang membaca
names.txtlalu mencetak semua nama dengan nomor urut. - Script yang menerima input expense, lalu menyimpannya ke
expenses.txt. - Function
read_numbers(path)yang mengembalikan list angka dari file. - Module
formatter.pyberisi functionformat_currency(amount). - Error handling untuk input angka yang tidak valid.
Checklist sebelum lanjut
Saat membaca error file, periksa tiga hal: dari folder mana command dijalankan, path apa yang sebenarnya dibentuk, dan apakah format isi file sesuai asumsi program. Cetak path yang dipakai jika perlu; debugging yang baik mengubah dugaan menjadi bukti.
Untuk exception, jangan hanya membuat error hilang. Pastikan fallback tidak menyamarkan data yang rusak. Jika file transaksi tidak ada, list kosong mungkin tepat untuk aplikasi baru, tetapi pesan yang jelas atau error mungkin lebih tepat untuk laporan wajib. Respons harus mengikuti konteks program.
Lanjut ke OOP Python
Sekarang kamu sudah bisa memecah kode ke function dan module. Berikutnya kita akan membahas object-oriented programming dengan cara praktis: kapan class membantu, kapan function biasa lebih cukup, dan bagaimana dataclass membuat object data lebih nyaman. Lanjut ke Object-Oriented Python untuk Pemula.
Kalau ingin mengulang bagian sebelumnya, baca lagi Python Functions dan Struktur Data.
Artikel Terkait
Lanjutkan membaca topik yang masih satu konteks.
Jalur Belajar Python Fundamental: Rangkuman Seri dan Langkah Lanjut
Rangkuman praktis seri Python Fundamental berisi enam materi, skill utama, checkpoint latihan, dan langkah lanjut setelah membuat project CLI.
Mini Project Python: Build CLI Expense Tracker dari Nol
Bangun CLI expense tracker dengan Python dari nol memakai input, JSON file storage, function, dataclass, error handling, dan testing dasar.
Python Project Structure: venv, pip, Requirements, dan Testing
Belajar menyusun project Python yang rapi dengan struktur folder, virtual environment, pip, requirements.txt, .env, pytest, dan entry point sederhana.
Object-Oriented Python untuk Pemula: Class, Object, dan Dataclass
Belajar OOP Python secara praktis: class, object, method, __init__, dataclass, composition, dan kapan OOP benar-benar membantu.