Parameter & Return Value — Python

Parameter & Return Value Positional vs Keyword Arguments def buat_profil(nama, umur, kota="Jakarta"): return {"nama": nama, "umur": umur, "kota": kota} #…

Parameter adalah pintu masuk data ke fungsi, dan return pintu keluarnya. Pelajaran ini membahas semua cara mengisi pintu masuk itu dan mengeluarkan lebih dari satu nilai. Bayangin formulir pesanan di meja kasir Warung Kopi Pak Darto: kolom "menu" wajib diisi, kolom "jumlah" sudah tercetak angka 1, dan ada kotak "catatan" yang boleh diisi berapa baris pun. Kolomnya bisa diisi urut dari atas, atau dengan menulis nama kolomnya.

🧪 Tebakan cepat: def tambah_pesanan(item, pesanan=[]) menambahkan item ke pesanan lalu me-return-nya. Dipanggil tambah_pesanan("kopi susu"), lalu print(tambah_pesanan("teh manis")). Yang tercetak ['teh manis'] atau ['kopi susu', 'teh manis']? Tebak dulu, jawabannya ada di bagian "Default yang berupa list".

Positional dan keyword argument

def buat_pesanan(menu, jumlah=1, gula="normal"):
    return f"{jumlah} {menu}, gula {gula}"

print(buat_pesanan("kopi susu", 2))               # 2 kopi susu, gula normal
print(buat_pesanan("teh manis", gula="sedikit"))  # 1 teh manis, gula sedikit
print(buat_pesanan(jumlah=3, menu="kopi susu"))   # 3 kopi susu, gula normal

Mengembalikan beberapa nilai

def ringkas(harga):
    return min(harga), max(harga), sum(harga)

termurah, termahal, total = ringkas([15000, 5000, 12000])
print(termurah, termahal, total)       # 5000 15000 32000
print(ringkas([15000, 5000, 12000]))   # (5000, 15000, 32000)

return juga bisa dipakai lebih awal untuk keluar dari fungsi, misalnya if orang == 0: return None di awal fungsi pembagi tagihan, sebelum membagi dengan nol.

*args: argumen sebanyak apa pun

def total(*harga):
    print(harga)
    return sum(harga)

print(total(15000, 5000, 12000))   # (15000, 5000, 12000) lalu 32000
print(total())                     # () lalu 0

**kwargs: keyword sebanyak apa pun

** mengumpulkan semua keyword argument yang gak punya parameter sendiri jadi satu dict: pasangan nama: nilai di antara kurung kurawal (dibahas di pelajaran Dictionary). Yang lazim ditulis **kwargs, keyword arguments.

Panggilan yang sama, catat("kopi susu", "teh manis", meja=4), diterima atau ditolak tergantung parameternya:

def Hasil
def catat(menu1, menu2): TypeError: catat() got an unexpected keyword argument 'meja'
def catat(*menu): TypeError: catat() got an unexpected keyword argument 'meja'
def catat(**info): TypeError: catat() takes 0 positional arguments but 2 were given
def catat(*menu, **info): menu jadi ('kopi susu', 'teh manis'), info jadi {'meja': 4}

Default yang berupa list

def tambah_pesanan(item, pesanan=[]):
    pesanan.append(item)
    return pesanan

print(tambah_pesanan("kopi susu"))   # ['kopi susu']
print(tambah_pesanan("teh manis"))   # ['kopi susu', 'teh manis']

.append(item) menambah item ke ujung list. Nilai default dibuat sekali, saat baris def dijalankan, bukan tiap kali fungsi dipanggil. Jadi semua panggilan tanpa argumen kedua memakai list yang sama, dan isinya menumpuk. Panggilan kedua mencetak ['kopi susu', 'teh manis']. Itu jawaban tebakannya.

Perbaikannya: pakai None sebagai default, lalu bikin list baru di dalam fungsi.

def tambah_pesanan(item, pesanan=None):
    if pesanan is None:
        pesanan = []
    pesanan.append(item)
    return pesanan

Sekarang tambah_pesanan("kopi susu") lalu tambah_pesanan("teh manis") memberi ['kopi susu'] lalu ['teh manis']. is None mengecek apakah nilainya memang None.

📌 Keyword-only dan urutan parameter

Parameter yang ditulis setelah * (atau setelah *args) cuma bisa diisi dengan nama:

def catat(menu1, menu2, *, meja):
    print(menu1, menu2, meja)

catat("kopi susu", "teh manis", meja=4)   # kopi susu teh manis 4
catat("kopi susu", "teh manis", 4)        # TypeError: catat() takes 2 positional arguments but 3 were given

Gunanya, angka yang maknanya gak jelas (4 itu meja? jumlah?) wajib disebut namanya. Urutan resmi parameter: parameter biasa, *args, parameter keyword-only (boleh pakai default), lalu **kwargs. Kebalikannya juga ada saat memanggil: jumlah(*[1, 2, 3]) membongkar list jadi tiga positional, dan jumlah(**{"a": 10, "b": 20, "c": 30}) membongkar dict jadi keyword.

⚠️ Jebakan yang sering ketemu

TL;DR: Positional argument diisikan menurut urutan, keyword argument menurut nama, dan positional selalu ditulis duluan. Default dipakai kalau argumennya gak dikirim (hitung(5) dengan b=10 hasilnya 15). return a, b, c mengembalikan tuple yang bisa dibongkar ke beberapa nama sekaligus. *args mengumpulkan positional sisa jadi tuple, **kwargs mengumpulkan keyword sisa jadi dict, dan def f(a, b, *args, **kwargs) menerima f(1, 2, x=3). Parameter setelah * cuma bisa diisi dengan nama. Jangan pakai list sebagai default: dia dibuat sekali dan dipakai bersama, jadi pakai None.

Yang akan kamu pelajari