Type hint adalah catatan di kode yang menyebut tipe sebuah parameter, nilai return, atau variabel, misalnya "total ini int". Bayangin label di toples dapur Warung Kopi Pak Darto: "GULA", "GARAM". Labelnya memberi tahu isi yang seharusnya, tapi toplesnya gak menolak kalau garam dimasukkan ke toples gula. Yang menangkap kesalahan itu pemeriksa yang membaca labelnya sebelum warung buka. Di Python, pemeriksa itu tool seperti mypy, dan Python sendiri tetap menjalankan kodenya apa adanya.
🧪 Tebakan cepat:
def total_harga(harga: int, jumlah: int) -> int:badannyareturn harga * jumlah. Program memanggilprint(total_harga("15000", 3)), dengan"15000"sebagai string. Python berhenti dengan error, atau mencetak sesuatu? Tebak dulu, jawabannya ada di bagian "Hint gak dipaksa saat program jalan".
Menulis type hint
def diskon(total: int) -> int:
if total >= 100000:
return 15
elif total >= 50000:
return 10
elif total >= 25000:
return 5
else:
return 0
hari_ini: int = 89000
print(diskon(hari_ini)) # 10
total: intartinya "parametertotalseharusnyaint". Hint ditulis sesudah nama parameter, dipisah titik dua.-> intsebelum titik dua di akhir barisdefmenyebut tipe nilai return-nya. Fungsi yang gak me-return apa-apa ditulis-> None.hari_ini: int = 89000memberi hint ke variabel: nama, titik dua, tipe, lalu=dan nilainya.- Tipe dasarnya yang sudah kamu kenal:
int,float,str,bool. Hasilnya tetap10: hint gak mengubah cara kodenya jalan.
Hint gak dipaksa saat program jalan
def total_harga(harga: int, jumlah: int) -> int:
return harga * jumlah
print(total_harga("15000", 3))
$ python3 warung.py
150001500015000
Python membaca hint-nya dan menyimpannya (total_harga.__annotations__ berisi {'harga': <class 'int'>, 'jumlah': <class 'int'>, 'return': <class 'int'>}), tapi gak memeriksanya. String dikali 3 artinya diulang tiga kali, jadi hasilnya teks "15000" tiga kali berderet, bukan 45000. Programnya jalan tanpa error, dan angkanya diam-diam salah. Itu jawaban tebakannya.
Ganti "15000" dengan None, dan baru ada error. Itu pun datang dari operasi * di baris 2, bukan dari hint-nya:
Traceback (most recent call last):
File "/home/darto/warung.py", line 4, in <module>
print(total_harga(None, 3))
~~~~~~~~~~~^^^^^^^^^
File "/home/darto/warung.py", line 2, in total_harga
return harga * jumlah
~~~~~~^~~~~~~~
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
mypy: pemeriksa yang membaca hint
mypy membaca kodemu tanpa menjalankannya, lalu membandingkan tiap pemakaian dengan hint-nya. Pasang sekali dengan pip install mypy, lalu:
$ mypy warung.py
warung.py:4: error: Argument 1 to "total_harga" has incompatible type "str"; expected "int" [arg-type]
Found 1 error in 1 file (checked 1 source file)
warung.py:4menunjuk baris 4, tempat"15000"dikirim.[arg-type]jenis kesalahannya: argumen yang tipenya gak cocok.- Kesalahannya ketemu sebelum programnya jalan, jadi gak ada angka salah yang sempat tercetak di struk.
- Editor seperti VS Code bisa memakai pemeriksa sejenis, dan menandai baris yang sama selagi kamu mengetik.
- Hapus hint-nya (
def total_harga(harga, jumlah):) dan mypy menjawabSuccess: no issues found in 1 source file. Fungsi tanpa hint gak diperiksa sama sekali. Python-nya sendiri tetap mencetak150001500015000.
Tipe untuk list dan dict
def laris(penjualan: dict[str, int], minimal: int = 3) -> list[str]:
return [menu for menu, jumlah in penjualan.items() if jumlah >= minimal]
penjualan = {"kopi susu": 3, "teh manis": 4, "roti bakar": 2}
print(laris(penjualan)) # ['kopi susu', 'teh manis']
print(laris(penjualan, 2)) # ['kopi susu', 'teh manis', 'roti bakar']
list[str]artinya list yang isinya string.list[int]list berisi int.dict[str, int]artinya dictionary dengan key string dan value int, seperti penjualan hari ini.tuple[str, int]untuk tuple seperti("kopi susu", 3), danset[str]untuk set berisi string.- Sejak Python 3.9 tipe ini ditulis langsung dengan kurung siku, tanpa import. Gaya lama
List[int]butuhfrom typing import List; tanpa import itu, Python berhenti denganNameError: name 'List' is not defined. Did you mean: 'list'? - Parameter dengan hint dan default ditulis
minimal: int = 3.>=ikut menghitung angka yang tepat sama dengan batasnya: denganminimal2, roti bakar (2) ikut masuk.
Latihan pelajaran ini memakai pola yang sama untuk nilai ujian: filter_lulus(nilai: list[int], batas: int = 70) -> list[int].
Urutannya selalu begini: def nama(param: tipe) -> tipe_return:. Tanda -> dan tipe return-nya ada sebelum titik dua. list<int> gaya Java atau TypeScript, dan def rata(n: list[int]): -> float yang menaruh -> sesudah titik dua, dua-duanya ditolak dengan SyntaxError: invalid syntax.
Boleh kosong: X | None
menu.get(nama) memberi None kalau menunya gak ada. Hint-nya int | None, artinya "int, atau None":
def cari_harga(menu: dict[str, int], nama: str) -> int | None:
return menu.get(nama)
menu = {"kopi susu": 15000, "teh manis": 5000}
harga = cari_harga(menu, "es teh")
print(harga + 1000)
Python baru gagal saat jalan, TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'. mypy sudah menangkapnya sebelum itu:
$ mypy warung.py
warung.py:6: error: Unsupported operand types for + ("None" and "int") [operator]
warung.py:6: note: Left operand is of type "int | None"
Found 1 error in 1 file (checked 1 source file)
Perbaikannya, cek dulu dengan if harga is None: (is None mengecek apakah nilainya None), dan hitung di else. mypy pun menjawab Success.
Optional[int]darifrom typing import Optionalartinya sama denganint | None. Itu gaya sebelum Python 3.10, dan masih sering ketemu di kode lama.Union[int, str]daritypingsama denganint | str: salah satu dari keduanya.- Kalau hint-nya cuma
-> intpadahal bisaNone, mypy protes di barisreturn:Incompatible return value type (got "int | None", expected "int").
⚠️ Jebakan yang sering ketemu
- Mengira hint memeriksa tipe. Python tetap menjalankan
total_harga("15000", 3)dan mencetak150001500015000. Jalankan mypy, dan untuk data dari luar (input, file) ubah sendiri denganint(). - Sintaks bahasa lain.
list<int>dan-> floatsesudah titik dua jadiSyntaxError: invalid syntax. Tulislist[int], dan->sebelum titik dua. Listtanpa import.NameError: name 'List' is not defined. Pakailist[int]yang gak butuh import.- Lupa
None. Fungsi yang bisa me-returnNoneditulis-> int | None, lalu cekis Nonesebelum memakai hasilnya.
TL;DR: Type hint menulis tipe yang diharapkan: param: tipe di parameter, -> tipe sebelum titik dua di akhir def, dan nama: tipe = nilai di variabel. Python gak memaksa hint saat jalan: total_harga("15000", 3) dengan hint int tetap jalan dan mencetak 150001500015000. Tool seperti mypy membaca hint tanpa menjalankan kode dan melaporkan incompatible type sebelum program jalan; fungsi tanpa hint gak diperiksa. Koleksi ditulis dengan kurung siku tanpa import: list[int], dict[str, int], tuple[str, int], set[str]. Nilai yang boleh kosong: int | None, sama dengan Optional[int]. Bentuknya selalu def rata(n: list[int]) -> float:, bukan list<int>.