Sejak Python 3.8, kita dapat menetapkan nilai ke variabel langsung dari dalam sebuah ekspresi memakai operator walrus :=. Operator ini menyelesaikan masalah sederhana namun sering muncul: sebuah nilai perlu dihitung lalu langsung dipakai dalam kondisi while atau if, tanpa menulis perhitungan dua kali atau membuat variabel sementara di luar blok. Pada Chapter ini kita akan membedah cara kerja :=, pola pemakaian yang paling berguna, dan kapan operator ini justru membuat kode lebih sulit dibaca.

Cara Kerja Assignment Expression #

Perintah penugasan biasa (n = 15) adalah statement: ia tidak menghasilkan nilai dan tidak bisa ditanam di dalam ekspresi lain. Operator := adalah kebalikannya — sebuah assignment expression: interpreter Python mengevaluasi sisi kanan, mengikat hasilnya ke variabel di sisi kiri, lalu mengembalikan nilai tersebut sebagai hasil ekspresi sehingga bisa langsung dipakai.

python
print(n := 15)
print(n + 1)

data = [7, 14, 21, 28]
i = 0
while (x := data[i]) < 20:
    print("masih di bawah 20:", x)
    i += 1
print("berhenti di", x)

Output yang Dihasilkan:

text
15
16
masih di bawah 20: 7
masih di bawah 20: 14
berhenti di 21

Mari kita telaah baris-baris pentingnya:

  1. Baris 1 (print(n := 15)): interpreter mengikat 15 ke variabel n, kemudian ekspresi n := 15 bernilai 15, sehingga fungsi print() menerima 15 dan mencetaknya.
  2. Baris 2 (print(n + 1)): variabel n sudah terisi dari baris sebelumnya, sehingga cetakan berikutnya adalah 16.
  3. Baris 6 (while (x := data[i]) < 20:): setiap iterasi membaca data[i] sekali, menyimpannya ke x, sekaligus membandingkan nilainya dengan 20 — tiga pekerjaan dalam satu baris.
  4. Baris 9 (print("berhenti di", x)): variabel x tetap bisa diakses setelah loop berhenti karena := mengikat variabel pada scope yang mengelilingi ekspresi, sama seperti penugasan biasa.

Pola Nyata: Loop Konsumsi dan Regex #

Dua tempat di mana := paling sering terasa manfaatnya adalah loop yang membaca sumber data (antrean, input(), file.read()) dan pencocokan regex di dalam if. Mari kita lihat pola konsumsi antrean sampai bertemu penanda kosong:

python
antrian = ["sinkronisasi data", "kirim email", "arsipkan log", ""]

# pop(0) dievaluasi sekali per iterasi, hasilnya langsung diikat ke perintah
while (perintah := antrian.pop(0)):
    print("Menjalankan:", perintah)

print("Antrian kosong, loop berhenti")
print("Sisa antrian:", antrian)

Output yang Dihasilkan:

text
Menjalankan: sinkronisasi data
Menjalankan: kirim email
Menjalankan: arsipkan log
Antrian kosong, loop berhenti
Sisa antrian: []

Pada iterasi keempat, antrian.pop(0) mengembalikan string kosong "" — nilainya tetap diikat ke perintah lebih dulu, baru dinyatakan falsy sehingga loop berhenti. Karena pop(0) ikut mengeluarkan elemen tersebut dari list, baris Sisa antrian: [] pada output menampilkan list yang sudah kosong.

Pola while (baris := sumber()): ini adalah bentuk yang sama dengan idiom klasik while (blok := file.read(4096)): untuk membaca file per potongan, atau while (perintah := input()): untuk membaca ketikan pengguna. Tanpa :=, kita terpaksa memanggil antrian.pop(0) dua kali (sekali untuk diperiksa, sekali untuk dipakai) atau menulis satu iterasi persiapan sebelum loop dimulai.

Pola kedua adalah pencocokan regex. Method search() pada module re mengembalikan objek Match atau None; dengan :=, hasil pencocokan diikat ke variabel dan langsung diuji kebenarannya dalam satu if:

python
import re

pola_error = re.compile(r"ERROR (\d+): (.+)")

log = [
    "INFO server mulai",
    "ERROR 500: database tidak terjangkau",
    "INFO sinkronisasi selesai",
    "ERROR 404: endpoint tidak ditemukan",
]

for baris in log:
    if (m := pola_error.search(baris)):
        kode, pesan = m.groups()
        print(f"Galat {kode}: {pesan}")

print("Selesai memindai", len(log), "baris log")

Output yang Dihasilkan:

text
Galat 500: database tidak terjangkau
Galat 404: endpoint tidak ditemukan
Selesai memindai 4 baris log

Tanpa operator walrus, blok if harus dipecah menjadi dua langkah: m = pola_error.search(baris) diikuti if m:. Materi kelompok tangkapan groups() telah dibahas pada Chapter Groups dan Captures.

Walrus di Dalam Comprehension #

Comprehension mendapat manfaat unik: := memungkinkan kita menyaring berdasarkan nilai hasil hitung sekaligus memakai nilai itu pada hasil akhir, melanjutkan materi Chapter List Comprehensions:

python
harga = [15000, 82000, 47500, 99000, 23000]

laporan = [(h, d) for h in harga if (d := round(h * 0.1)) >= 8000]
print(laporan)
print("Nilai d setelah comprehension:", d)

Output yang Dihasilkan:

text
[(82000, 8200), (99000, 9900)]
Nilai d setelah comprehension: 2300

Pada baris comprehension tersebut, d := round(h * 0.1) dihitung sekali per elemen, dipakai oleh kondisi >= 8000, lalu dipakai lagi oleh pasangan (h, d). Tanpa :=, perhitungan round(h * 0.1) harus ditulis dua kali atau comprehension harus dipecah menjadi loop biasa.

Perhatikan baris terakhir output: variabel d bocor ke scope luar dan berisi nilai dari iterasi terakhir. Di dalam comprehension, := mengikat variabel pada scope yang mengelilingi comprehension, bukan scope lokal comprehension — perilaku yang disengaja namun mudah mengejutkan.

Kapan Tidak Memakai Walrus #

Operator := bukan penggajaran =. Pedoman komunitas cukup jelas: pakai := ketika operator tersebut menghapus pengulangan atau variabel sementara; hindari ketika operator tersebut hanya memindahkan kejanggalan ke dalam satu baris yang padat.

SituasiRekomendasi
Nilai dari input(), read(), pop(), re.search() dipakai segera setelah diperiksa:= sangat membantu
Kondisi dan hasil comprehension memakai hasil hitung yang sama:= menghapus duplikasi
Ekspresi sederhana yang hanya dihitung sekaliPenugasan biasa lebih jelas
Menumpuk beberapa := dalam satu barisPecah menjadi beberapa baris

Beberapa bentuk juga bukan sekadar gaya buruk, tetapi langsung ditolak interpreter Python. Simpan sebagai demo.py lalu jalankan python3 demo.py:

python
x := 10

Output yang Dihasilkan (dicetak interpreter Python ke stderr):

text
  File "demo.py", line 1
    x := 10
      ^^
SyntaxError: invalid syntax

Penugasan telanjang adalah statement, bukan ekspresi, sehingga wajib memakai =. Di dalam comprehension, := pada kondisi if juga wajib dibungkus tanda kurung:

python
data = [4, 17, 8, 23]
hasil = [x for x in data if y := x % 2]
print(hasil)

Output yang Dihasilkan (dicetak interpreter Python ke stderr):

text
  File "demo.py", line 2
    hasil = [x for x in data if y := x % 2]
                                  ^^
SyntaxError: invalid syntax