Nama parameter pada function Python bukan sekadar label internal — begitu pengguna mulai memanggil buat_koneksi(host=...), nama host menjadi bagian dari kontrak publik API dan tidak bisa diubah tanpa merusak kode mereka. Sejak Python 3.8, penanda / pada signature memungkinkan kita menyatakan parameter sebagai positional-only: wajib dikirim secara posisi dan tidak boleh disebut namanya. Chapter ini melanjutkan materi dasar pada Chapter Positional-Only dan Keyword-Only Parameters dengan fokus pada anatomi lengkap signature, alasan desain di balik stdlib, dan panduan memilih mode parameter untuk API kita sendiri.

Anatomi Lengkap Signature #

Python mengenal empat zona parameter yang dipisahkan tiga penanda: / (batas kiri), * (batas kanan), dan *args/**kwargs untuk sisa argumen. Signature berikut menampilkan semua zona inti sekaligus:

python
def buat_koneksi(host, port, /, timeout=30, *, retry=3):
    print(f"host={host}, port={port}, timeout={timeout}, retry={retry}")


buat_koneksi("db.example.com", 5432)
buat_koneksi("db.example.com", 5432, timeout=10)
buat_koneksi("db.example.com", 5432, 10, retry=5)

percobaan = [
    ("host sebagai keyword  :", lambda: buat_koneksi(host="db.example.com", port=5432)),
    ("retry sebagai positional:", lambda: buat_koneksi("db.example.com", 5432, 30, 5)),
]

for label, panggil in percobaan:
    try:
        panggil()
    except TypeError as e:
        print(label, "->", e)

Output yang Dihasilkan:

text
host=db.example.com, port=5432, timeout=30, retry=3
host=db.example.com, port=5432, timeout=10, retry=3
host=db.example.com, port=5432, timeout=10, retry=5
host sebagai keyword  : -> buat_koneksi() got some positional-only arguments passed as keyword arguments: 'host, port'
retry sebagai positional: -> buat_koneksi() takes from 2 to 3 positional arguments but 4 were given

Mari kita bedah zona-zona pada signature buat_koneksi:

  1. Baris 1 (def buat_koneksi(host, port, /, ...)): host dan port berada di kiri /, sehingga keduanya positional-only — pemanggil boleh memakai posisi (buat_koneksi("db", 5432)), tetapi menyebut host= atau port= memicu TypeError seperti pada output keempat.
  2. Baris 1 (..., /, timeout=30, *, ...)): timeout berada di antara / dan *, sehingga parameter ini positional-or-keyword — cara panggil paling fleksibel.
  3. Baris 1 (*, retry=3)): retry berada di kanan *, sehingga parameter ini keyword-only — boleh dikirim dengan nama saja, dan pemanggilan posisi ..., 30, 5) ditolak seperti pada output kelima.
  4. Baris 4-6 (tiga pemanggilan sah): ketiganya menggambarkan rentang cara panggil yang diterima; perhatikan bahwa timeout bisa dikirim secara posisi (10) maupun nama (timeout=10).

Mengapa Positional-Only: Kebebasan Mengganti Nama #

Manfaat utama / adalah kebebasan refactor. Jika host dan port dikunci sebagai positional-only, kita bisa menggantinya menjadi alamat dan port di versi berikutnya tanpa merusak satu pun pemanggilan lama — pengguna tidak pernah menyebut nama tersebut. Sebaliknya, parameter positional-or-keyword yang sudah dipakai dengan nama terkunci selamanya.

Standar library memakai teknik ini secara luas. Function bawaan seperti len() dan str.replace() menolak keyword untuk seluruh parameternya:

python
import inspect

print(inspect.signature(len))

try:
    len(obj=[1, 2, 3])
except TypeError as e:
    print("len     :", e)

try:
    "kopi-gayo".replace(old="-", new="_")
except TypeError as e:
    print("replace :", e)

Output yang Dihasilkan:

text
(obj, /)
len     : len() takes no keyword arguments
replace : str.replace() takes no keyword arguments

Baris (obj, /) adalah signature len() yang dilaporkan module inspect: penanda / setelah satu-satunya parameternya menegaskan bahwa len(obj=x) tidak sah. Penamaan seperti obj dipilih demi deskripsi umum, bukan untuk dipanggil — dengan positional-only, pengembang CPython bebas mengubah penamaan internal tersebut tanpa memengaruhi pengguna.

Alasan kedua adalah menghindari kopling palsu. Pada function yang parameternya sederhana dan urutannya sudah bermakna (misalnya pow(base, exp)), memaksa keyword justru menambah kebisingan. Positional-only juga melindungi dari tabrakan nama: def proses(data, /, **kwargs) menjamin kwargs["data"] tidak pernah bertabrakan dengan parameter data.

Panduan Memilih Mode Parameter #

Rekap singkat: parameter setelah penanda * menjadi keyword-only dan hanya boleh dipanggil dengan nama — materi dasarnya ada pada Chapter Positional-Only dan Keyword-Only Parameters. Tabel berikut merangkum keputusan desain keempat zona sebagai satu frame:

Zona signatureCara panggil sahKapan dipilihContoh stdlib
Kiri / (positional-only)Hanya posisiNama tidak bermakna, ingin bebas refactor, mencegah tabrakan dengan **kwargslen(obj, /), str.replace()
Antara / dan *Posisi atau namaDefault zona; mayoritas function biasapow(base, exp, mod=None)
Kanan * (keyword-only)Hanya namaOpsi opsional yang perlu eksplisit di lokasi panggilsorted(iterable, *, key, reverse)
*args / **kwargsSisa argumen bebasWrapper dan penerus argumenfunctools.wraps