Argumen disahkan oleh penugasan . Alasan di balik ini ada dua:
- parameter yang diteruskan sebenarnya adalah referensi ke objek (tetapi referensi dilewatkan oleh nilai)
- beberapa tipe data bisa berubah, tetapi yang lain tidak
Begitu:
Jika Anda melewatkan objek yang dapat diubah ke dalam metode, metode tersebut mendapatkan referensi ke objek yang sama dan Anda dapat mengubahnya untuk kesenangan hati Anda, tetapi jika Anda mengubah referensi dalam metode tersebut, ruang lingkup luar tidak akan tahu apa-apa tentang hal itu, dan setelah itu Anda sudah selesai, referensi luar masih akan menunjuk ke objek asli.
Jika Anda meneruskan objek yang tidak dapat diubah ke suatu metode, Anda masih tidak dapat memutar ulang referensi luar, dan Anda bahkan tidak bisa bermutasi objek.
Untuk membuatnya lebih jelas, mari kita memiliki beberapa contoh.
Daftar - tipe yang bisa berubah
Mari kita coba memodifikasi daftar yang diteruskan ke metode:
def try_to_change_list_contents(the_list):
print('got', the_list)
the_list.append('four')
print('changed to', the_list)
outer_list = ['one', 'two', 'three']
print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)
Keluaran:
before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']
Karena parameter yang diteruskan adalah referensi outer_list
, bukan salinannya, kita dapat menggunakan metode daftar mutasi untuk mengubahnya dan memiliki perubahan yang tercermin dalam lingkup luar.
Sekarang mari kita lihat apa yang terjadi ketika kita mencoba mengubah referensi yang dilewatkan sebagai parameter:
def try_to_change_list_reference(the_list):
print('got', the_list)
the_list = ['and', 'we', 'can', 'not', 'lie']
print('set to', the_list)
outer_list = ['we', 'like', 'proper', 'English']
print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)
Keluaran:
before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']
Karena the_list
parameter dilewatkan oleh nilai, menetapkan daftar baru untuk itu tidak berpengaruh bahwa kode di luar metode dapat melihat. Itu the_list
adalah salinan outer_list
referensi, dan kami memiliki the_list
menunjuk ke daftar baru, tetapi tidak ada cara untuk mengubah di mana outer_list
menunjuk.
String - tipe yang tidak dapat diubah
Itu tidak berubah, jadi tidak ada yang bisa kita lakukan untuk mengubah isi string
Sekarang, mari kita coba untuk mengubah referensi
def try_to_change_string_reference(the_string):
print('got', the_string)
the_string = 'In a kingdom by the sea'
print('set to', the_string)
outer_string = 'It was many and many a year ago'
print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)
Keluaran:
before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago
Sekali lagi, karena the_string
parameter dilewatkan oleh nilai, menetapkan string baru untuk itu tidak berpengaruh bahwa kode di luar metode bisa dilihat. Itu the_string
adalah salinan dari outer_string
rujukan, dan kami telah the_string
menunjuk ke string baru, tetapi tidak ada cara untuk mengubah ke mana rujukan outer_string
.
Saya harap ini membersihkan sedikit.
EDIT: Telah dicatat bahwa ini tidak menjawab pertanyaan yang awalnya diajukan oleh David, "Apakah ada yang bisa saya lakukan untuk meneruskan variabel dengan referensi yang sebenarnya?". Mari kita kerjakan itu.
Bagaimana kita mengatasi ini?
Seperti yang ditunjukkan oleh jawaban Andrea, Anda dapat mengembalikan nilai baru. Ini tidak mengubah cara segala sesuatu dilewatkan, tetapi membiarkan Anda mendapatkan informasi yang Anda inginkan:
def return_a_whole_new_string(the_string):
new_string = something_to_do_with_the_old_string(the_string)
return new_string
# then you could call it like
my_string = return_a_whole_new_string(my_string)
Jika Anda benar-benar ingin menghindari menggunakan nilai balik, Anda bisa membuat kelas untuk menyimpan nilai Anda dan meneruskannya ke fungsi atau menggunakan kelas yang ada, seperti daftar:
def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
new_string = something_to_do_with_the_old_string(stuff_to_change[0])
stuff_to_change[0] = new_string
# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)
do_something_with(wrapper[0])
Meskipun ini agak rumit.