Fungsi Python: Beda print dan return, dan Kenapa Muncul None
Kenapa None muncul di bawah hasil fungsi Python? Beda print dan return, parameter default, return banyak nilai, UnboundLocalError, plus soal tracing UTS.

Di halaman ini
- Kenapa muncul None di bawah hasil fungsi?
- Beda print dan return dalam satu tabel
- Soal tracing: print di dalam fungsi dan print(f(x))
- Parameter default dan return banyak nilai
- Parameter default
- Return banyak nilai
- Variabel lokal vs global dan UnboundLocalError
- Dua soal tracing gaya UTS: slicing dan aliasing list
- Soal 1. Slicing string
- Soal 2. Aliasing list
- Kesalahan yang sering terjadi di soal fungsi
- FAQ
- Apakah fungsi wajib punya return?
- Apa yang terjadi kalau ada dua return dalam satu fungsi?
- Kenapa return tidak menampilkan apa-apa di layar?
- Bagaimana cara mengembalikan dua nilai dari fungsi?
- Apakah boleh mengubah variabel global dari dalam fungsi?
Perbedaan print dan return di Python: print hanya menampilkan nilai ke layar, sedangkan return mengirim nilai kembali ke kode yang memanggil fungsi. Fungsi yang tidak punya return tetap mengembalikan sesuatu, yaitu None. Itulah sebabnya kata None sering tercetak di bawah hasil yang kamu harapkan.
Semua output di artikel ini diperoleh dengan menjalankan kodenya di Python 3.12, jadi kamu bisa mencocokkan jawaban tracing-mu baris per baris.
Kenapa muncul None di bawah hasil fungsi?
Ini gejala yang paling sering ditanyakan di praktikum:
def luas(p, l):
print(p * l)
print(luas(4, 5))
Output:
20
None
Urutan kejadiannya:
luas(4, 5)dipanggil. Di dalam fungsi,print(p * l)mencetak 20.- Fungsi selesai tanpa
return, sehingga nilai yang dikembalikan adalahNone. print(...)di luar menerimaNonedan mencetaknya.
Perbaikannya ada dua, tergantung kebutuhan. Kalau fungsi memang bertugas menghitung, ganti print(p * l) dengan return p * l, lalu biarkan print di luar. Kalau fungsi bertugas menampilkan, panggil saja luas(4, 5) tanpa membungkusnya dengan print.
Pilihan pertama hampir selalu lebih baik. Fungsi yang mengembalikan nilai bisa dipakai lagi: luas(4, 5) + luas(2, 3) menghasilkan 26. Fungsi yang hanya mencetak tidak bisa dijumlahkan, karena None + None langsung memicu TypeError.
Beda print dan return dalam satu tabel
print(x) | return x | |
|---|---|---|
| Tujuan | Menampilkan ke layar | Mengirim nilai ke pemanggil |
| Fungsi berhenti? | Tidak, baris berikutnya tetap jalan | Ya, fungsi langsung selesai |
| Nilai bisa disimpan di variabel? | Tidak | Ya, hasil = f() |
| Jumlah per fungsi | Boleh berkali-kali | Hanya satu yang dieksekusi per panggilan |
| Kalau tidak ada | Tidak ada yang tampil | Fungsi mengembalikan None |
Baris kedua tabel ini yang paling sering keluar di soal tracing. Kode yang ditulis setelah return dan berada di jalur yang sama tidak akan pernah dijalankan.
Soal tracing: print di dalam fungsi dan print(f(x))
Soal seperti ini muncul di hampir setiap UTS Dasar Pemrograman. Tentukan output persisnya:
def f(x):
print("masuk", x)
if x > 3:
return x * 2
print("kecil")
a = f(5)
b = f(2)
print(a, b)
Langkah tracing:
f(5): cetakmasuk 5. Karena 5 > 3, fungsi mengembalikan 10 dan langsung berhenti. Barisprint("kecil")dilewati. Nilaiamenjadi 10.f(2): cetakmasuk 2. Karena 2 > 3 salah, lanjut keprint("kecil"). Fungsi selesai tanpareturn, sehinggabbernilaiNone.print(a, b)mencetak10 None.
Output lengkap:
masuk 5
masuk 2
kecil
10 None
Perhatikan bahwa baris a = f(5) tidak mencetak 10. Penugasan ke variabel tidak menampilkan apa pun. Angka 10 baru terlihat di baris terakhir.
Parameter default dan return banyak nilai
Parameter default
def diskon(harga, persen=10):
return harga - harga * persen / 100
diskon(50000)menghasilkan45000.0, karenapersenmemakai nilai default 10.diskon(50000, 25)menghasilkan37500.0.diskon(persen=50, harga=80000)menghasilkan40000.0. Argumen bernama boleh ditulis dalam urutan apa pun.
Hasilnya bertipe float (ada .0) karena operator / di Python 3 selalu menghasilkan float, walaupun pembagiannya habis.
Jebakan yang sering dipakai dosen adalah default berupa list:
def catat(x, daftar=[]):
daftar.append(x)
return daftar
print(catat(1))
print(catat(2))
Outputnya [1] lalu [1, 2], bukan [1] lalu [2]. List default dibuat sekali saja ketika fungsi didefinisikan, lalu dipakai bersama oleh semua panggilan. Cara amannya: tulis daftar=None, lalu di dalam fungsi if daftar is None: daftar = [].
Return banyak nilai
def statistik(data):
return min(data), max(data), sum(data) / len(data)
hasil = statistik([70, 85, 90, 65])
print(hasil)
terendah, tertinggi, rata = statistik([70, 85, 90, 65])
print(terendah, tertinggi, rata)
Output:
(65, 90, 77.5)
65 90 77.5
Python sebenarnya hanya mengembalikan satu nilai, yaitu sebuah tuple berisi tiga elemen. Rata-ratanya . Tuple itu bisa disimpan utuh, atau dibongkar langsung ke tiga variabel. Jumlah variabel di kiri harus sama dengan jumlah elemen, kalau tidak muncul ValueError.
Variabel lokal vs global dan UnboundLocalError
skor = 10
def tambah():
skor = skor + 5
return skor
tambah()
Kode ini gagal dengan:
UnboundLocalError: cannot access local variable 'skor' where it is not associated with a value
Di Python versi lama (3.10 ke bawah), pesannya local variable 'skor' referenced before assignment. Artinya sama.
Penyebabnya: karena ada penugasan skor = ... di dalam fungsi, Python menganggap skor sebagai variabel lokal di seluruh fungsi itu. Ketika ruas kanan skor + 5 dihitung, skor lokal belum punya nilai. Variabel global skor = 10 tidak dilirik sama sekali.
Ada dua perbaikan:
- Tambahkan
global skordi baris pertama fungsi. Setelah dipanggil,tambah()mengembalikan 15 danskorglobal juga menjadi 15. - Lebih baik, kirim nilainya sebagai parameter dan kembalikan hasilnya:
def tambah(nilai): return nilai + 5, laluskor = tambah(skor). Fungsi seperti ini lebih mudah diuji dan tidak diam-diam mengubah variabel di luar.
Yang membingungkan, fungsi yang hanya membaca variabel global tanpa menugasinya tidak error. def baca(): return skor * 2 berjalan normal dan mengembalikan 20 selama skor bernilai 10. Masalah hanya muncul ketika ada penugasan.
Dua soal tracing gaya UTS: slicing dan aliasing list
Soal 1. Slicing string
s = "MAHASISWA"
print(s[1:5], s[-3:], s[::2], s[::-1], s[2:-2], s[5:1])
Tulis dulu indeks tiap huruf, lalu ambil sesuai aturan s[awal:akhir:langkah] dengan indeks akhir tidak ikut.
| Indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|---|
| Huruf | M | A | H | A | S | I | S | W | A |
| Indeks negatif | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
| Ekspresi | Indeks yang diambil | Hasil |
|---|---|---|
s[1:5] | 1, 2, 3, 4 | AHAS |
s[-3:] | 6, 7, 8 | SWA |
s[::2] | 0, 2, 4, 6, 8 | MHSSA |
s[::-1] | 8 sampai 0 | AWSISAHAM |
s[2:-2] | 2 sampai 6 | HASIS |
s[5:1] | tidak ada | string kosong |
Output: AHAS SWA MHSSA AWSISAHAM HASIS (ada spasi di ujung, karena elemen terakhir adalah string kosong). Bagian s[5:1] menjebak: tanpa langkah negatif, awal yang lebih besar dari akhir menghasilkan string kosong, bukan error.
Soal 2. Aliasing list
a = [1, 2, 3]
b = a
c = a[:]
b.append(4)
c.append(5)
print(a, b, c)
| Baris | a | b | c | Catatan |
|---|---|---|---|---|
a = [1, 2, 3] | [1, 2, 3] | |||
b = a | [1, 2, 3] | [1, 2, 3] | b menunjuk list yang sama | |
c = a[:] | [1, 2, 3] | [1, 2, 3] | [1, 2, 3] | c adalah salinan baru |
b.append(4) | [1, 2, 3, 4] | [1, 2, 3, 4] | [1, 2, 3] | a ikut berubah |
c.append(5) | [1, 2, 3, 4] | [1, 2, 3, 4] | [1, 2, 3, 5] | a tidak terpengaruh |
Output: [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 5]. Kuncinya, b = a tidak menyalin list. Keduanya adalah dua nama untuk satu objek yang sama, sedangkan a[:] membuat list baru.
Aturan yang sama berlaku untuk parameter fungsi. Kalau fungsi menjalankan daftar.append(99) pada list yang dikirim, list asli di luar ikut berubah. Tapi kalau di dalam fungsi ditulis daftar = [0], itu hanya mengarahkan nama lokal ke list baru, dan list asli tidak tersentuh.
Kesalahan yang sering terjadi di soal fungsi
- Menulis
return print(x). Fungsi mencetak x, lalu mengembalikanNone(nilai kembali dariprint). - Menaruh return di dalam loop padahal maksudnya setelah loop. Fungsi berhenti di iterasi pertama, jadi penjumlahan hanya berisi satu elemen. Periksa indentasi
return. - Lupa menyimpan hasil. Memanggil
hitung(5)sendirian tidak menampilkan apa pun dan nilainya hilang. Tulishasil = hitung(5)atauprint(hitung(5)). - Menganggap
b = amenyalin list, lalu bingung kenapa list asli ikut berubah. - Menjawab soal tracing dengan menulis
10di barisa = f(5). Penugasan tidak mencetak.
Kalau programmu justru berhenti dengan pesan error, mulai dari error Python untuk pemula. Fungsi yang memanggil dirinya sendiri dibahas di tracing rekursi Python dengan call stack, dan fungsi di dalam class ada di OOP Python: class, self, dan inheritance.
FAQ
Apakah fungsi wajib punya return?
Tidak. Fungsi yang tugasnya menampilkan sesuatu atau mengubah list boleh tanpa return, dan otomatis mengembalikan None. Masalah hanya muncul kalau kamu memakai hasilnya, misalnya mencetak atau menjumlahkannya.
Apa yang terjadi kalau ada dua return dalam satu fungsi?
Hanya return pertama yang tercapai yang dijalankan. Pola if ...: return A lalu return B di luar if itu wajar, karena dalam satu panggilan hanya salah satunya yang tercapai.
Kenapa return tidak menampilkan apa-apa di layar?
Karena return hanya mengirim nilai ke pemanggil. Di mode interaktif (Python shell atau sel Jupyter), nilai ekspresi terakhir memang ditampilkan otomatis, sehingga terlihat seperti dicetak. Di berkas .py yang dijalankan biasa, kamu harus memakai print.
Bagaimana cara mengembalikan dua nilai dari fungsi?
Tulis return x, y. Python membungkusnya menjadi tuple (x, y), yang bisa dibongkar dengan p, q = fungsi().
Apakah boleh mengubah variabel global dari dalam fungsi?
Boleh dengan kata kunci global, tapi sebaiknya dihindari di tugas. Mengirim nilai lewat parameter dan menerima hasilnya lewat return membuat alur data terlihat jelas, dan penilai praktikum biasanya lebih menyukainya.
