🐍 📗 Bagian 2 (Struktur Data, OOP & Proyek) • Modul 07 100% Standar Industri & Vokasi

Fungsi, Parameter, Return & Lambda

Mendefinisikan fungsi dengan def, parameter posisional & keyword, default arguments, arbitrary arguments (*args, **kwargs), scope variabel, dan anonim lambda.

Target Pembelajaran:
  • 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 anonim lambda.
Anatomi Komponen Fungsi Python: def, Parameter, Type Hints, Docstring, dan return.
Gambar 7.1: Anatomi Komponen Fungsi Python: def, Parameter, Type Hints, Docstring, dan return.

1. Ruang Lingkup Variabel: Aturan LEGB

Hierarki Pencarian Ruang Lingkup Variabel: Local -> Enclosing -> Global -> Built-in.
Gambar 7.2: Hierarki Pencarian Ruang Lingkup Variabel: Local -> Enclosing -> Global -> Built-in.

Saat sebuah nama variabel dipanggil di dalam fungsi, Python mencari variabel tersebut dengan urutan hierarki LEGB:

🪜 Hierarki Pencarian Variabel (LEGB Rule):
  • 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).
python (contoh_scope.py)
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!

python (jebakan_default.py)
# ❌ 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`

Alur Pengemasan Parameter Dinamis: *args (Tuple) dan **kwargs (Dictionary).
Gambar 7.3: Alur Pengemasan Parameter Dinamis: *args (Tuple) dan **kwargs (Dictionary).

Simbol bintang satu *args mengumpulkan semua argumen posisional tambahan menjadi sebuah Tuple, sedangkan bintang dua **kwargs mengumpulkan semua keyword arguments menjadi Dictionary.

python
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

🧠 Kuis Cepat: Berapakah hasil eksekusi berikut?
kali = lambda a, b=2: a * b
print(kali(5))
Klik untuk melihat jawaban & pembahasan
Jawaban: 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)).

Kriteria: Fungsi dapat dipanggil hanya dengan generate_invoice(42) ataupun dengan kustomisasi prefix generate_invoice(42, prefix="TRX").
📋 Cheat Sheet: Definisi Fungsi & Modularisasi
Cheat Sheet
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)
🛠️ Praktikum Terkait

Jobsheet 04: Modularitas, Scope & Lambda

Rancang aplikasi kalkulator finansial modular dengan pemisahan fungsi perhitungan pajak, bunga pinjaman, dan cicilan.

⚠️ Perangkap Pemula: Lupa Keyword return & Scope Variabel
Waspada Error

Mengira fungsi otomatis mengembalikan hasil perhitungan tanpa keyword return, atau memodifikasi variabel global secara langsung.

Kode Salah (Memicu Error)
# 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 Benar & Aman
# 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)
Penyebab & Solusi: Fungsi tanpa return selalu mengembalikan None. Untuk menjaga modularitas yang bersih, hindari ketergantungan variabel global dan komunikasikan data lewat argumen parameter serta return.
💡 Tips Pythonic: Default Mutable Argument & Multiple Return
Standar PEP 8

Waspadai perangkap mutable default parameter dan gunakan tuple unpacking untuk mengembalikan banyak nilai dari fungsi.

Kurang Pythonic (Hindari)
# 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 Way (Direkomendasikan)
# 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)
PENTING: Parameter default seperti 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.

2 Soal Pilihan Ganda
Q1

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.

Q2

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.