Fungsi, Parameter, Return & Lambda
Mendefinisikan fungsi dengan def, parameter posisional & keyword, default arguments, arbitrary arguments (*args, **kwargs), scope variabel, dan anonim lambda.
- Mampu merancang fungsi dengan Type Hinting dan Return Values.
- Memahami aturan pencarian variabel LEGB Scope.
- Mengetahui bahaya dari Mutable Default Parameter Trap.
- Menggunakan
*args,**kwargs, dan fungsi anonimlambda.
1. Ruang Lingkup Variabel: Aturan LEGB
Saat sebuah nama variabel dipanggil di dalam fungsi, Python mencari variabel tersebut dengan urutan hierarki LEGB:
- L (Local): Variabel yang didefinisikan di dalam fungsi yang sedang berjalan.
- E (Enclosing): Variabel pada fungsi pembungkus (pada kasus fungsi di dalam fungsi/closure).
- G (Global): Variabel yang dideklarasikan di level utama file modul.
- B (Built-in): Modul bawaan Python (seperti fungsi
len,range,print).
x = "GLOBAL"
def fungsi_luar():
x = "ENCLOSING"
def fungsi_dalam():
x = "LOCAL"
print("x di dalam:", x) # Output: LOCAL
fungsi_dalam()
print("x di luar:", x) # Output: ENCLOSING
fungsi_luar()
print("x utama:", x) # Output: GLOBAL
2. Jebakan Mutable Default Argument
Nilai default pada parameter fungsi hanya dievaluasi SATU KALI saat fungsi pertama kali dibaca oleh interpreter (waktu definisi fungsi), bukan setiap kali fungsi dipanggil!
# ❌ BAHAYA: Menggunakan list kosong sebagai default parameter
def tambah_daftar(item, list_tujuan=[]):
list_tujuan.append(item)
return list_tujuan
print(tambah_daftar("Apel")) # ['Apel']
print(tambah_daftar("Jeruk")) # ['Apel', 'Jeruk'] (Bukan ['Jeruk']! List lama tetap tersimpan)
# ✔️ SOLUSI PYTHONIC: Gunakan None sebagai sentinel default
def tambah_daftar_aman(item, list_tujuan=None):
if list_tujuan is None:
list_tujuan = []
list_tujuan.append(item)
return list_tujuan
print(tambah_daftar_aman("Apel")) # ['Apel']
print(tambah_daftar_aman("Jeruk")) # ['Jeruk'] (Aman!)
3. Parameter Dinamis: `*args` dan `**kwargs`
Simbol bintang satu *args mengumpulkan semua argumen posisional tambahan menjadi sebuah Tuple, sedangkan bintang dua **kwargs mengumpulkan semua keyword arguments menjadi Dictionary.
def log_transaksi(user_id, *nominal, **metadata):
total = sum(nominal)
print(f"User: {user_id} | Total: Rp {total:,.0f}")
for k, v in metadata.items():
print(f" > {k}: {v}")
log_transaksi("USR-001", 50000, 120000, 30000, metode="QRIS", status="Berhasil")
4. Kuis Pemahaman & Latihan
kali = lambda a, b=2: a * b
print(kali(5))
Klik untuk melihat jawaban & pembahasan
10
Penjelasan: Lambda juga mendukung default parameter. Karena argumen
b tidak dikirim saat pemanggilan kali(5), nilai default b=2 digunakan, sehingga 5 * 2 = 10.
Tantangan 7: Generator Nomor Faktur Otomatis
Buat fungsi generate_invoice(nomor_urut, prefix="INV", tahun=2026) yang mengembalikan string nomor faktur dengan format INV/2026/00042 (nomor urut memiliki padding angka 5 digit dengan fungsi str(nomor_urut).zfill(5)).
generate_invoice(42) ataupun dengan kustomisasi prefix generate_invoice(42, prefix="TRX").
| Sintaks / Perintah | Keterangan Fungsi |
|---|---|
def nama_fungsi(params): |
Mendeklarasikan blok fungsi modular baru |
return nilai |
Mengembalikan hasil keluaran data dari fungsi ke pemanggil |
def func(a, b=10): |
Fungsi dengan nilai default parameter cadangan |
def func(*args, **kwargs): |
Menerima argumen posisi (tuple) dan keyword (dict) dinamis |
return val1, val2 |
Multiple return: mengembalikan banyak nilai sekaligus via tuple |
lambda x: x * 2 |
Anonymous function (fungsi satu baris tanpa nama) |
Jobsheet 04: Modularitas, Scope & Lambda
Rancang aplikasi kalkulator finansial modular dengan pemisahan fungsi perhitungan pajak, bunga pinjaman, dan cicilan.
Mengira fungsi otomatis mengembalikan hasil perhitungan tanpa keyword return, atau memodifikasi variabel global secara langsung.
# 1. Lupa return (Otomatis menghasilkan None):
def hitung_diskon(total):
hasil = total * 0.1
# Lupa: return hasil
potongan = hitung_diskon(100000)
print(potongan + 5000) # TypeError: NoneType + int
# 2. UnboundLocalError:
saldo = 1000
def tarik_tunai():
saldo = saldo - 100 # Error modifikasi lokal
# Solusi 1: Selalu sertakan return eksplisit
def hitung_diskon(total):
return total * 0.1
# Solusi 2: Oper nilai lewat parameter & kembalikan via return
saldo = 1000
def tarik_tunai(s, jumlah):
return s - jumlah
saldo = tarik_tunai(saldo, 100)
return selalu mengembalikan None. Untuk menjaga modularitas yang bersih, hindari ketergantungan variabel global dan komunikasikan data lewat argumen parameter serta return.
Waspadai perangkap mutable default parameter dan gunakan tuple unpacking untuk mengembalikan banyak nilai dari fungsi.
# Kurang Pythonic / Bahaya (Mutable default parameter)
def tambah_pesanan(menu, daftar=[]): # BUG: daftar dipakai bersama!
daftar.append(menu)
return daftar
def hitung_persegi(sisi):
keliling = 4 * sisi
luas = sisi * sisi
return [keliling, luas] # Mengembalikan list manual
# Pythonic (Gunakan None sebagai default penanda)
def tambah_pesanan(menu, daftar=None):
if daftar is None:
daftar = []
daftar.append(menu)
return daftar
def hitung_persegi(sisi):
return 4 * sisi, sisi * sisi # Multiple return otomatis menjadi Tuple
# Unpacking langsung saat memanggil:
kel, luas = hitung_persegi(5)
daftar=[] hanya dievaluasi satu kali saat fungsi didefinisikan, sehingga nilainya akan termodifikasi terus-menerus di antar pemanggilan. Gunakan daftar=None sebagai standar PEP 8.
Cek Pemahaman Mandiri
Uji pemahaman Anda terhadap konsep bab ini dengan feedback evaluasi instan.
Apa fungsi dari parameter *args dan **kwargs pada deklarasi fungsi?
💡 Pembahasan: *args (Arbitrary Positional Arguments) mengumpulkan argumen posisi ke dalam Tuple, sedangkan **kwargs (Arbitrary Keyword Arguments) mengumpulkan pasangan parameter kunci=nilai ke dalam Dictionary.
Manakah penulisan fungsi anonim (Lambda) yang benar untuk menghitung kuadrat dari suatu bilangan x?
💡 Pembahasan: Sintaks lambda di Python adalah lambda parameter: ekspresi. Hasil dari ekspresi akan otomatis di-return tanpa perlu kata kunci return.