Kursus Python / Type hint untuk parameter, hasil fungsi, dan None
Type hint adalah anotasi yang menjelaskan tipe masukan dan hasil yang diharapkan oleh suatu fungsi. Anotasi membantu pembaca, editor, dan pemeriksa statis, tetapi Python tidak otomatis mengubah atau menolak nilai berdasarkan anotasi tersebut. Karena itu, kontrak tipe perlu dibedakan dari validasi nilai saat program berjalan.
Membaca tipe parameter dan hasil fungsi
Pada parameter amount: int, nama parameter adalah amount dan tipe yang diharapkan adalah bilangan bulat. Bagian -> str menjelaskan bahwa fungsi mengembalikan string. Keduanya memberi informasi tentang penggunaan fungsi, bukan instruksi konversi. Mengirim string angka ke parameter beranotasi int tetap mengirim string.
Anotasi koleksi menjelaskan isinya: list[int] berarti daftar bilangan bulat, sedangkan dict[str, str] berarti dictionary dengan kunci dan nilai string. Penulisan str | None mengizinkan string atau nilai khusus None yang menandakan tidak ada hasil. Untuk mengikuti contoh ini, gunakan Python 3.12 atau lebih baru dan lingkungan virtual proyek.
Mulailah dari fungsi yang menjadi batas antarkomponen, misalnya fungsi pembaca data atau penghitung total. Anotasi yang cocok dengan hasil sebenarnya lebih berguna daripada menambahkan nama tipe pada setiap variabel. Jika fungsi kadang tidak menemukan data, tuliskan kemungkinan tersebut dalam tipe hasil agar pemanggil menanganinya.
Dokumentasi typing Python menjelaskan peran anotasi. Kode yang membaca anotasi secara dinamis perlu memperhatikan aturan evaluasi anotasi pada versi Python yang dipakai; latihan ini hanya memakai anotasi untuk menjelaskan kontrak dan pemeriksaan statis.
Membandingkan anotasi dengan validasi saat eksekusi
Buat folder latihan tersendiri, lalu simpan seluruh kode berikut sebagai hints.py dengan UTF-8. Aktifkan lingkungan virtual proyek dan jalankan python hints.py dari folder itu. Jika perintah interpreter Anda di luar lingkungan virtual adalah python3, gunakan nama tersebut secara konsisten.
def format_amount(amount: int) -> str:
if type(amount) is not int or amount < 0:
raise ValueError("invalid amount")
return f"{amount:,} KRW"
def find_name(names: dict[str, str], key: str) -> str | None:
return names.get(key)
print(format_amount(8000))
print(find_name({"e1": "lunch"}, "missing"))
try:
format_amount("8000")
except ValueError:
print("rejected")
Hasil yang diharapkan:
8,000 KRW
None
rejected
Panggilan pertama memformat 8000 sebagai string dengan pemisah ribuan. Tulisan KRW di sini hanya label pada contoh, bukan konversi mata uang. Pencarian kunci missing menghasilkan None karena kunci itu tidak ada dalam dictionary.
Panggilan terakhir sengaja mengirim "8000". Yang menolaknya adalah kondisi type(amount) is not int, kemudian raise ValueError; anotasi tidak melakukan penolakan itu. Penangan except menangkap kesalahan dan mencetak rejected. Mekanisme ini mengikuti penanganan exception dengan try dan raise.
Coba ganti argumen terakhir menjadi -1, lalu True, dan jalankan ulang setelah setiap perubahan. Keduanya ditolak oleh validasi contoh: nilai negatif melanggar batas, sedangkan True tidak memiliki tipe persis int. Nilai nol diterima. Setelah membandingkan hasil, kembalikan argumen ke string semula agar percobaan pemeriksa statis berikutnya sesuai.
Menjalankan mypy dan memahami diagnostiknya
mypy adalah alat pemeriksa tipe statis: alat ini menganalisis hubungan tipe pada kode tanpa menjalankan program tersebut. Pemasangannya opsional dan memerlukan akses ke sumber paket. Pasang pada lingkungan virtual proyek agar tidak mengubah paket proyek lain, lalu jalankan pemeriksaan file:
python -m pip install mypy
python -m mypy hints.py
Contoh awal memang mengandung kesalahan tipe yang disengaja. mypy melaporkan bahwa argumen string pada format_amount("8000") tidak cocok dengan parameter int, walaupun eksekusi Python selesai setelah menangani ValueError. Nomor baris dan kalimat diagnostik bisa berbeda menurut versi alat; perhatikan lokasi panggilan dan tipe yang dibandingkan.
Untuk perbandingan, salin file menjadi hints_fixed.py, lalu hapus seluruh bagian try/except terakhir beserta panggilan buruk dan pencetakannya. Jangan menyisakan blok try kosong. Jalankan python -m mypy hints_fixed.py: file yang diperbaiki seharusnya lolos pemeriksaan. File asli tetap tersedia untuk mengulangi percobaan penolakan.
Kelulusan pemeriksaan tidak menjamin jumlah nonnegatif. Mengganti argumen menjadi -1 masih sesuai tipe int, tetapi fungsi tetap menolaknya saat dieksekusi. Jangan mengganti semua anotasi menjadi Any sekadar menghilangkan peringatan; tentukan apakah kesalahan berasal dari pemanggil, kontrak fungsi, atau data yang belum divalidasi. Lihat panduan awal mypy untuk cara membaca pemeriksaan bertahap.
| Pemeriksaan | Pertanyaan yang dijawab |
|---|---|
| Analisis statis | Apakah tipe argumen, operasi, dan hasil konsisten dengan kontrak yang dianalisis? |
| Validasi saat eksekusi | Apakah nilai nyata memenuhi batas, format, dan persyaratan data aplikasi? |
Menangani None dan data dari luar program
Hasil find_name harus diperiksa sebelum dipakai sebagai string. Simpan hasilnya dalam variabel, gunakan kondisi is None untuk menangani ketiadaan, dan panggil metode string hanya pada cabang yang memiliki nama. Memanggil upper() pada None menimbulkan AttributeError. Mengganti anotasi hasil menjadi str tanpa mengubah perilaku fungsi hanya menyembunyikan kontrak yang salah.
Data eksternal juga tidak menjadi benar hanya karena diberi anotasi. String "8000" dari formulir atau dokumen JSON perlu diproses menurut kebijakan masukan: ditolak, atau dikonversi secara eksplisit dengan penanganan kegagalan lalu diperiksa batasnya. Konversi dan pemeriksaan tersebut harus tampak pada alur program, bukan diasumsikan dari tanda : int.
Gunakan pemeriksaan statis untuk menemukan ketidaksesuaian kontrak sebelum eksekusi, lalu uji jalur nilai valid, nilai salah, dan data yang tidak ditemukan. Ketersediaan berkas, respons jaringan, serta aturan bisnis tetap perlu ditangani saat program berjalan karena tidak dijamin oleh anotasi tipe.




