Pengiriman Referensi Python: Kasus Penggunaan Mutable vs Immutable

1. Perbedaan Antara Pass‑by‑Value dan Pass‑by‑Reference

Di Python, ada dua cara untuk mengirim argumen ke fungsi: pass‑by‑value dan pass‑by‑reference.

  • Pass‑by‑value: Metode di mana salinan nilai dikirim ke fungsi sebagai argumen; memodifikasi parameter di dalam fungsi tidak memengaruhi variabel asli.
  • Pass‑by‑reference: Metode di mana referensi (alamat) ke variabel dikirim ke fungsi, sehingga perubahan yang dilakukan di dalam fungsi tercermin pada variabel asli.

Di Python, perilaku ini bervariasi tergantung pada sifat objek. Perilaku “pass‑by‑reference” Python terutama berlaku untuk tipe data yang mutable dan dapat secara signifikan memengaruhi cara kode berperilaku, sehingga penting untuk memahaminya dengan benar.

2. Karakteristik Objek di Python

Di Python, semua data diperlakukan sebagai objek, dan berdasarkan karakteristik objeknya mereka diklasifikasikan sebagai immutable (tidak dapat diubah) atau mutable (dapat diubah). Perbedaan ini memengaruhi cara mereka berperilaku ketika dilewatkan sebagai argumen ke fungsi.

  • Objek immutable: objek yang tidak dapat dimodifikasi setelah dibuat. Contohnya meliputi integer (int), floating‑point (float), string (str), tuple (tuple). Karena tipe data ini tidak dapat diubah setelah dibuat, operasi pada mereka di dalam fungsi tidak memengaruhi pemanggil meskipun dilewatkan sebagai referensi.
  • Objek mutable: objek yang dapat dimodifikasi setelah dibuat. Contohnya meliputi list (list), dictionary (dict), set (set). Karena perubahan pada tipe data ini di dalam fungsi tercermin pada pemanggil, mereka sangat dipengaruhi oleh perilaku pass‑by‑reference Python.

年収訴求

3. Cara Python Mengirim Argumen

Di Python, ketika Anda mengirim argumen ke sebuah fungsi, referensi ke objek yang dikirim. Perilaku ini kadang disebut “pass‑by‑object‑reference.” Berikut ini kami akan menelusuri contoh konkret yang menggambarkan perilaku Python tergantung pada apakah objek immutable atau mutable.

3.1 Objek Immutable

Ketika Anda mengirim objek immutable ke sebuah fungsi, penugasan nilai baru di dalam fungsi membuat objek baru dan tidak memengaruhi objek asli.

Contoh: Mengirim Integer Immutable

def modify_number(num):
    num = num * 2
    print("Number inside the function:", num)

original_num = 5
modify_number(original_num)
print("Number outside the function:", original_num)

Output:

Number inside the function: 10
Number outside the function: 5

Penjelasan

Di dalam fungsi modify_number, variabel num digandakan, tetapi hal ini tidak memengaruhi original_num di luar fungsi. Karena integer bersifat immutable, objek baru dibuat ketika nilai baru ditetapkan, sehingga original_num tetap tidak berubah.

3.2 Objek Mutable

Sebaliknya, ketika objek mutable dikirim ke sebuah fungsi, referensinya juga digunakan di dalam fungsi. Akibatnya, perubahan yang dilakukan di dalam fungsi tercermin pada objek asli juga.

Contoh: Mengirim List Mutable

def add_item(my_list):
    my_list.append("Added element")
    print("List inside the function:", my_list)

original_list = ["Element 1", "Element 2"]
add_item(original_list)
print("List outside the function:", original_list)

Output:

List inside the function: ['Element 1', 'Element 2', 'Added element']
List outside the function: ['Element 1', 'Element 2', 'Added element']

Penjelasan

Karena list bersifat mutable, perubahan yang dilakukan di dalam fungsi add_item langsung tercermin pada original_list di luar fungsi. Dengan cara ini, objek mutable dibagikan antara dalam dan luar fungsi, sehingga modifikasi di dalam fungsi juga memengaruhi pemanggil.

4. Peringatan dan Langkah Pencegahan untuk Pass‑by‑Reference

Melewatkan objek yang dapat diubah ke fungsi di Python dapat menyebabkan perilaku yang tidak terduga. Berikut beberapa langkah pencegahan untuk menghindari masalah tersebut.

4.1 Gunakan Salinan Objek

Jika Anda ingin memodifikasi sebuah objek di dalam fungsi, Anda dapat menghindari memengaruhi objek asli dengan menyalinnya sebelum melakukan perubahan. Di Python, Anda dapat menggunakan modul copy untuk membuat salinan dangkal (copy.copy) atau salinan dalam (copy.deepcopy).

Contoh: Menggunakan Deep Copy untuk Menghindari Masalah Objek Mutable

import copy

def add_item(my_list):
    my_list_copy = copy.deepcopy(my_list)
    my_list_copy.append("Added element")
    print("List inside the function (copy):", my_list_copy)

original_list = ["Element 1", "Element 2"]
add_item(original_list)
print("List outside the function:", original_list)

Output:

List inside the function (copy): ['Element 1', 'Element 2', 'Added element']
List outside the function: ['Element 1', 'Element 2']

Penjelasan
Dengan menggunakan deepcopy, sebuah objek baru dibuat di dalam fungsi, sehingga daftar asli tidak terpengaruh. Ini memungkinkan perubahan independen di dalam dan di luar fungsi.

4.2 Gunakan None untuk Argumen Default

Hindari menetapkan objek mutable sebagai argumen default fungsi; disarankan untuk menggunakan None sebagai nilai default dan membuat objek baru di dalam fungsi.

Contoh: Cara Aman Membuat Argumen Default None

def add_item(my_list=None):
    if my_list is None:
        my_list = []
    my_list.append("New element")
    print("List inside the function:", my_list)
    return my_list

# When no list is passed
result = add_item()
print("Returned list:", result)

# When a list is passed
existing_list = ["Element 1", "Element 2"]
result = add_item(existing_list)
print("Returned list:", result)
print("Original list:", existing_list)

Output:

List inside the function: ['New element']
Returned list: ['New element']
List inside the function: ['Element 1', 'Element 2', 'New element']
Returned list: ['Element 1', 'Element 2', 'New element']
Original list: ['Element 1', 'Element 2', 'New element']

Penjelasan
Dengan menggunakan argumen default None dan menghasilkan daftar baru di dalam fungsi, Anda dapat mencegah daftar eksternal dimodifikasi secara tidak terduga. Menetapkan None sebagai argumen default membuat jelas apakah harus membuat daftar baru atau menggunakan yang diberikan.

年収訴求

5. Contoh Praktis: Kode untuk Memperdalam Pemahaman tentang Pass-by-Reference

Mari kita tinjau apa yang telah kita bahas dengan contoh praktis.

Contoh: Memodifikasi Kunci dan Nilai Dictionary

Dictionary adalah objek mutable, sehingga operasi yang dilakukan di dalam fungsi memengaruhi dictionary di luar fungsi. Contoh di bawah menunjukkan perilaku saat mengubah kunci dan nilai dictionary.

def modify_dict(my_dict):
    my_dict["new key"] = "new value"
    print("Dictionary inside the function:", my_dict)

original_dict = {"key1": "value1", "key2": "value2"}
modify_dict(original_dict)
print("Dictionary outside the function:", original_dict)

Output:

Dictionary inside the function: {'key1': 'value1', 'key2': 'value2', 'new key': 'new value'}
Dictionary outside the function: {'key1': 'value1', 'key2': 'value2', 'new key': 'new value'}

Penjelasan
Karena dictionary bersifat mutable, penambahan yang dilakukan di dalam fungsi juga tercermin dalam original_dict di luar fungsi. Seperti list, dictionary dapat memengaruhi pemanggil karena mereka dilewatkan dengan referensi.

6. Ringkasan

“Pass-by-reference” di Python berperilaku berbeda tergantung pada karakteristik objek, sehingga memahaminya diperlukan untuk meningkatkan keandalan kode Anda. Khususnya, untuk menghindari perilaku yang tidak terduga akibat melewatkan referensi ke objek mutable, disarankan untuk menggunakan penyalinan dan argumen default None.

Poin Ringkasan

  • Perbedaan antara pass-by-value dan pass-by-reference : Di Python, apakah modifikasi di dalam fungsi memengaruhi variabel asli tergantung pada sifat objeknya.
  • Immutable vs. mutable : Objek immutable di Python tidak mencerminkan perubahan yang dibuat di dalam fungsi, sedangkan objek mutable dibagikan antara dalam dan luar fungsi melalui passing referensi.
  • Strategi mitigasi : Untuk objek mutable, metode seperti menggunakan deepcopy dari modul copy, atau menetapkan argumen default ke None, efektif untuk menghindari perilaku tak terduga.

Saya harap artikel ini telah memperdalam pemahaman Anda tentang passing referensi di Python. Gunakan pengetahuan ini untuk menerapkan kode yang efisien dan lebih sedikit error.