python 12 July 2026

Bagian 7: Fungsi — Membuat Kode yang Bisa Dipakai Lagi, dan Lagi, tanpa Capek Mengetik

Bagian 7: Fungsi — Membuat Kode yang Bisa Dipakai Lagi, dan Lagi, tanpa Capek Mengetik

Saya masih ingat hari pertama saya mengajar loop di kelas XI RPL 2. Satu siswa — namanya Rizki, duduk di bangku paling belakang — menanyakan: *”Pak, kalau saya mau pakai kode ini di program lain, harus *copy-paste* ya?”*

Saya tersenyum. *”Bisa. Tapi bayangkan kalau kamu salah satu huruf di tengah *copy-paste-an itu. Kamu harus perbaiki di sepuluh tempat berbeda.”

Dia mengangguk pelan. “Jadi… bikin sekali, dipakai di mana aja?”

“Bingo. Itu namanya fungsi.”


Kenapa Harus Punya Fungsi?

Bayangkan Anda punya resep kue. Setiap kali mau bikin kue, Anda tidak hafal bahan dan langkahnya dari nol — Anda buka catatan resep, ikuti, jadi kue. Mau bikin besok? Buka resep yang sama. Mau kasih ke teman? Fotokopi resepnya.

Fungsi di Python itu resep. Anda tulis sekali, panggil kapan saja, di mana saja.

💡 Tips dari kelas: Siswa suka nanya, “Pak, kalo saya cuma bikin program kecil, perlu bikin fungsi nggak?” Jawab saya: “Kalau kamu masak mie instan sekali setahun, nggak butuh resep. Tapi kalau masak tiap hari? Tulis resepnya.”


1. Anatomi Fungsi: def, Parameter, dan return

Mari kita pecah. Fungsi minimal butuh tiga hal:

  • Nama (supaya bisa dipanggil)
  • Parameter (bahan-bahannya — opsional)
  • Return (hasilnya — opsional, tapi sangat disarankan)
# fungsi_sederhana.py
def sapa(nama):
    """Mengembalikan sapaan personal untuk nama yang diberikan."""
    pesan = f"Halo, {nama}! Selamat belajar Python."
    return pesan

# Memanggil fungsi
print(sapa("Rizki"))
print(sapa("Siti"))
print(sapa("Bambang"))

Output:

Halo, Rizki! Selamat belajar Python.
Halo, Siti! Selamat belajar Python.
Halo, Bambang! Selamat belajar Python.

Penjelasan:

  • def sapa(nama): → mendefinisikan fungsi bernama sapa yang menerima satu parameter bernama nama.
  • Baris """...""" itu docstring — dokumentasi internal. Tulis selalu. Masa depan Anda akan berterima kasih.
  • return pesan → mengembalikan nilai ke pemanggil. Tanpa return, fungsi hanya melakukan sesuatu tapi tidak menghasilkan apa-apa.

⚠️ Peringatan: Banyak siswa lupa return. Fungsi jalan, tapi variabel pemanggil jadi None. “Pak, kenapa hasil = sapa('Rizki') trus print(hasil) keluar None?” — karena fungsi nggak return apa-apa.


2. Parameter vs Argumen: Bahan vs Isi Mangkok

Istilah ini sering dibalik. Parameter = variabel di definisi fungsi (tempat nampung). Argumen = nilai asli yang dikirim saat memanggil.

# parameter_dan_argumen.py
def hitung_luas_persegi_panjang(panjang, lebar):
    """Menghitung luas persegi panjang."""
    luas = panjang * lebar
    return luas

# Argumen posisional (urutan harus sama)
luas_kamar = hitung_luas_persegi_panjang(4, 3)
print(f"Luas kamar: {luas_kamar} m²")

# Argumen keyword (urutan bebas, lebih jelas)
luas_halaman = hitung_luas_persegi_panjang(lebar=5, panjang=10)
print(f"Luas halaman: {luas_halaman} m²")

# Default parameter — opsional
def sapa_lengkap(nama, salam="Halo"):
    return f"{salam}, {nama}!"

print(sapa_lengkap("Rizki"))          # Pakai default
print(sapa_lengkap("Siti", "Selamat pagi"))  # Override default

Output:

Luas kamar: 12 m²
Luas halaman: 50 m²
Halo, Rizki!
Selamat pagi, Siti!

Penjelasan:

  • panjang, lebar di definisi = parameter.
  • 4, 3 dan lebar=5, panjang=10 = argumen.
  • salam="Halo" = default parameter. Kalau argumen tidak dikirim, pakai default.

💡 Tips: Gunakan keyword argument (nama=nilai) saat parameter banyak atau urutannya mudah salah. Kode jadi terbaca seperti bahasa manusia.


3. Scope Variabel: Siapa yang Bisa Lihat Siapa?

Ini yang paling bikin pusing siswa. Variabel di dalam fungsi (lokal) tidak kenal variabel di luar (global), dan sebaliknya — kecuali Anda minta izin.

# scope_variabel.py
nama_sekolah = "SMK RPL Negeri 1"  # Variabel GLOBAL

def perkenalan_siswa(nama):
    nama_sekolah = "SMK Swasta Jaya"  # Variabel LOKAL (beda dengan global!)
    kelas = "XI RPL 2"                # Variabel LOKAL
    print(f"{nama} sekolah di {nama_sekolah}, kelas {kelas}")

def info_sekolah():
    # Ingin akses variabel global? Bisa, tapi read-only kalau nggak pakai 'global'
    print(f"Sekolah saat ini: {nama_sekolah}")

perkenalan_siswa("Rizki")
info_sekolah()

# Error! 'kelas' hanya ada di dalam fungsi perkenalan_siswa
# print(kelas)  # Uncomment baris ini -> NameError

Output:

Rizki sekolah di SMK Swasta Jaya, kelas XI RPL 2
Sekolah saat ini: SMK RPL Negeri 1

Penjelasan:

  • nama_sekolah di luar fungsi = global.
  • nama_sekolah di dalam perkenalan_siswa = lokal (variabel baru, tak関係 dengan global).
  • kelas hanya hidup di dalam perkenalan_siswa. Mati saat fungsi selesai.

⚠️ Peringatan nyata: Saya pernah lihat siswa bikin variabel total = 0 di luar, lalu di dalam fungsi total += 1 tanpa global total. Python marah: UnboundLocalError. Variabel global di dalam fungsi: read-only kecuali dideklarasikan global.


4. Fungsi yang Mengembalikan Banyak Nilai (Tuple)

Python bisa return lebih dari satu nilai — sebetulnya dia pack jadi tuple.

# multi_return.py
def operasi_bilangan(a, b):
    """Mengembalikan 4 hasil operasi sekaligus."""
    tambah = a + b
    kurang = a - b
    kali = a * b
    bagi = a / b if b != 0 else "Tidak terbagi"
    return tambah, kurang, kali, bagi  # Otomatis jadi tuple

# Unpacking — bahasa Indonesia: "bongkar"
hasil_tambah, hasil_kurang, hasil_kali, hasil_bagi = operasi_bilangan(20, 4)

print(f"Tambah: {hasil_tambah}")
print(f"Kurang: {hasil_kurang}")
print(f"Kali: {hasil_kali}")
print(f"Bagi: {hasil_bagi}")

# Atau simpan sebagai tuple utuh
semua_hasil = operasi_bilangan(10, 3)
print(f"\nSemua hasil (tuple): {semua_hasil}")
print(f"Tipe: {type(semua_hasil)}")

Output:

Tambah: 24
Kurang: 16
Kali: 80
Bagi: 5.0

Semua hasil (tuple): (13, 7, 30, 3.3333333333333335)
Tipe: <class 'tuple'>

Penjelasan:

  • return a, b, c → Python bungkus jadi tuple.
  • x, y, z = fungsi()unpacking. Harus cocok jumlahnya.

💡 Metafora: return banyak nilai kayak bungkus nasi campur — nasi, ayam, sayur, sambal dibungkus satu plastik. Di rumah, Anda unpacking: nasi di piring, ayam di mangkuk, sambal di cekung.


5. Docstring: Surat Cinta untuk Diri Sendiri (dan Teman Tim)

Docstring bukan komentar biasa. Dia bisa diakses lewat kode — oleh help(), IDE, dan tools dokumentasi otomatis.

# docstring_contoh.py
def hitung_bmi(berat_kg, tinggi_m):
    """
    Menghitung Body Mass Index (BMI).

    Args:
        berat_kg (float): Berat badan dalam kilogram.
        tinggi_m (float): Tinggi badan dalam meter.

    Returns:
        float: Nilai BMI (berat / tinggi^2).

    Raises:
        ValueError: Jika tinggi <= 0.

    Contoh:
        >>> hitung_bmi(60, 1.65)
        22.04
    """
    if tinggi_m <= 0:
        raise ValueError("Tinggi harus lebih dari 0")
    return round(berat_kg / (tinggi_m ** 2), 2)

# Cara baca docstring:
print(hitung_bmi.__doc__)
print("---")
help(hitung_bmi)

Output (ringkas):

    Menghitung Body Mass Index (BMI).
    ...
    Contoh:
        >>> hitung_bmi(60, 1.65)
        22.04
---
Help on function hitung_bmi in module __main__:
hitung_bmi(berat_kg, tinggi_m)
    Menghitung Body Mass Index (BMI).
    ...

💡 Tips dari kelas: Wajibkan docstring di setiap tugas. Saya nilai: “Kodenya jalan tapi nggak ada docstring? Nilai dikurangi. Masa depan kamu (atau teman grup) bingku bacanya.”


6. Praktik Nyata: Modularisasi — Pecah File, Bukan Pusing

Fungsi jadi powerful kalau dipisah ke file tersendiri (modul). Lalu di-import.

File: matematika.py

# matematika.py
def tambah(a, b):
    return a + b

def kali(a, b):
    return a * b

def pangkat(base, eksponen):
    return base ** eksponen

# Variabel modul (konstana)
PI = 3.14159

File: main.py

# main.py
import matematika
from matematika import PI  # Import spesifik

print(f"5 + 3 = {matematika.tambah(5, 3)}")
print(f"4 x 6 = {matematika.kali(4, 6)}")
print(f"2^10 = {matematika.pangkat(2, 10)}")
print(f"PI = {PI}")

Output:

5 + 3 = 8
4 x 6 = 24
2^10 = 1024
PI = 3.14159

⚠️ Peringatan: Jangan from matematika import * (import semua). Nanti nama fungsi bentrok, bingung mana yang mana. Explisit lebih baik dari implisit.


Penutup

Fungsu itu jembatan antara “kode yang jalan sekali” dan “kode yang hidup lama”.

Saat Anda mulai menulis def, Anda berhenti jadi orang yang mengetik perintah — dan jadi orang yang membangun alat.

Rizki, siswa bangku belakang tadi? Semester berikutnya dia bikin library kecil buat teman-temannya: validasi_input, format_rupiah, generate_id. Dia bilang: “Pak, jadi gak perlu nulis ulang kode sama tiap project.”

Saya cuma balas: “Itu dia. Kamu udah nggak cuma coding. Kamu nge-engineer.”


Selanjutnya di Bagian 8: File I/O & Error Handling — Menyimpan Kenangan & Menangani Kekecewaan.
Karena program yang nggak bisa simpan data… cuma mimpi. Dan program yang nggak tahu error… cuma beruntung.

Sampai jumpa di bagian terakhir, para insinyur muda.