Kursus Python / Mengumpulkan dan membuka argumen dengan *args dan **kwargs
Dalam definisi fungsi, *args mengumpulkan argumen posisi tambahan menjadi tuple, sedangkan **kwargs mengumpulkan argumen keyword tambahan menjadi dictionary. Pada pemanggilan fungsi, * dan ** justru membuka koleksi menjadi argumen terpisah.
Bedakan mengumpulkan dan membuka argumen
Nama args dan kwargs merupakan kebiasaan penamaan; tanda bintang menentukan perilakunya. Karena itu, *amounts juga mengumpulkan argumen posisi. Argumen yang sudah terikat pada parameter bernama tidak ikut dikumpulkan sebagai argumen tambahan.
| Lokasi | Bentuk | Perilaku |
|---|---|---|
| Definisi | def f(*args) |
Mengumpulkan argumen posisi tambahan ke tuple |
| Definisi | def f(**kwargs) |
Mengumpulkan keyword tambahan ke dictionary |
| Pemanggilan | f(*values) |
Membuka unsur iterable sebagai argumen posisi |
| Pemanggilan | f(**options) |
Membuka mapping berkunci string sebagai keyword |
Parameter setelah *amounts bersifat keyword-only. Pada contoh berikut, fee harus diberikan dengan nama agar menjadi biaya tambahan tersendiri. Aturannya melanjutkan argumen posisi, keyword, dan nilai bawaan. Lihat juga dokumentasi argumen berjumlah bebas Python.
Jalankan jumlah pengeluaran dan deskripsi opsi
Simpan kode lengkap berikut sebagai varargs.py dengan encoding UTF-8 di folder latihan. Gunakan Python 3.12 atau lebih baru dan jalankan python varargs.py melalui terminal lingkungan proyek. Tidak diperlukan paket atau berkas masukan tambahan.
def total(*amounts, fee=0):
return sum(amounts) + fee
def describe(**fields):
return ", ".join(f"{key}={value}" for key, value in sorted(fields.items()))
values = [3500, 8000, 2500]
print(total(*values, fee=500))
options = {"category": "food", "currency": "KRW"}
print(describe(**options))
Keluaran yang diharapkan:
14500
category=food, currency=KRW
*values mengirim tiga bilangan sebagai tiga argumen posisi. Di dalam total, ketiganya menjadi tuple amounts. Jumlahnya 14000, lalu fee=500 menghasilkan 14500. Menulis total(values) mengirim satu list, bukan tiga bilangan, sehingga sum(amounts) gagal menjumlahkan integer awal dengan list tersebut.
**options mengirim dua pasangan keyword, lalu describe mengumpulkannya lagi sebagai dictionary. Fungsi mengurutkan pasangan berdasarkan kunci sebelum menggabungkan teks. Urutan keluaran kategori lalu mata uang berasal dari sorted(fields.items()), bukan dari kewajiban semua dictionary untuk selalu tersortir.
Nama currency di sini hanya informasi deskriptif. Program tidak mengonversi mata uang dan tidak memeriksa apakah nama kategori, kode mata uang, atau jumlah memenuhi aturan bisnis.
Periksa duplikasi dan pembukaan yang keliru
Kunci pada mapping yang dibuka dengan ** harus berupa string. Pemanggilan describe(**{1: "food"}) menghasilkan TypeError. Fungsi tanpa **kwargs juga menolak nama keyword yang tidak termasuk parameter yang diterimanya. Sebaliknya, contoh describe menerima nama string apa pun, termasuk salah ketik seperti curreny; keberhasilan pemanggilan bukan bukti bahwa opsi benar.
Memberikan keyword yang sama secara eksplisit dan melalui mapping, seperti total(1, fee=2, **{"fee": 3}), menghasilkan TypeError. Python tidak memilih nilai terakhir seperti pada penggabungan dictionary {**{"fee": 2}, **{"fee": 3}}. Periksa sumber opsi sebelum memanggil fungsi, dan tentukan aturan penggabungan secara sengaja jika memang diperlukan.
String juga iterable. total(*"123") mengirim string satu karakter "1", "2", dan "3", bukan bilangan 123 atau tiga integer. Penjumlahan contoh gagal karena tipe tersebut. Sementara itu, total(*123) gagal lebih awal karena integer tidak dapat dibuka sebagai iterable. Mekanisme pembukaan tidak memvalidasi atau mengonversi isi data; dokumentasi unpacking Python menunjukkan arah pengirimannya.
Pada pembungkus fungsi, def wrapper(*args, **kwargs) mengumpulkan panggilan, lalu return total(*args, **kwargs) meneruskannya. Menulis total(args, kwargs) justru mengirim tuple dan dictionary sebagai dua argumen posisi. Bentuk tersebut mengubah makna panggilan dan membuat contoh penjumlahan gagal.
Uji batas dan batasi antarmuka fungsi
- Tambahkan 0 ke
values, jalankan lagi, dan pastikan jumlah tetap 14500. Hapus penambahan tersebut setelah perbandingan. - Hilangkan
fee=500dari pemanggilan. Nilai bawaan nol menghasilkan 14000. Panggilantotal()menghasilkan nol, sedangkantotal(fee=500)menghasilkan 500. - Coba duplikasi keyword dan tipe masukan yang salah secara terpisah. Kesalahan yang tidak ditangani menghentikan program, sehingga uji gagal jangan diletakkan sebelum keluaran yang masih ingin diamati.
- Pulihkan kode asli dan cocokkan kedua baris keluaran sebelum memakai fungsi dalam program lain.
total(3500, 8000, 2500, 500) kebetulan memberi jumlah yang sama, tetapi 500 kini menjadi salah satu pengeluaran dan fee tetap nol. Hasil numerik yang sama tidak menjamin antarmuka dipakai dengan makna yang sama.
Gunakan argumen variabel ketika jumlah masukan memang bervariasi. Jika satu list memiliki arti yang jelas atau opsi yang diterima sudah tetap, parameter biasa sering lebih mudah diperiksa. Untuk penerusan ke API atau SQL, validasi nama yang diizinkan dan bidang wajib terlebih dahulu; menerima **kwargs tidak membuat data aman atau benar secara otomatis.




