Bağımsız değişkenler ödevle iletilir . Bunun arkasındaki mantık iki yönlüdür:
- geçirilen parametresinin a, referans bir nesneye (ancak bir referans değeri ile geçirilir)
- bazı veri türleri değiştirilebilir, ancak diğerleri
Yani:
Değiştirilebilir bir nesneyi bir yönteme geçirirseniz , yöntem aynı nesneye başvuru alır ve kalbinizin zevkine dönüştürebilirsiniz, ancak yöntemdeki başvuruyu yeniden bağlarsanız, dış kapsam bu konuda hiçbir şey bilmez ve sonra işiniz bittiğinde, dış referans yine de orijinal nesneyi gösterecektir.
Bir başarılı olursa iletmenin bir yöntemi nesne, yine dış başvuru rebind değildir, ve hatta nesne mutasyona olamaz.
Daha da netleştirmek için, bazı örnekler verelim.
Liste - değiştirilebilir bir tür
Bir yönteme geçirilen listeyi değiştirmeye çalışalım:
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)
Çıktı:
before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']
Aktarılan parametre outer_list
bir kopyası değil referans olduğu için , değişiklik listesi yöntemlerini kullanarak değiştirebiliriz ve değişikliklerin dış kapsama yansıtılmasını sağlayabiliriz.
Şimdi parametre olarak iletilen referansı değiştirmeye çalıştığımızda ne olacağını görelim:
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)
Çıktı:
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']
Yana the_list
parametre kendisine yeni bir liste atayarak, değeri tarafından kabul edildi yöntemle dışında kod görebildiğini hiçbir etkisi olmadı. the_list
Bir kopyası olan outer_list
referans ve biz vardı the_list
yeni listeye noktası, ama değiştirmek için hiçbir yolu yoktuouter_list
sivri.
String - değişmez tip
Değişmez, bu yüzden dizenin içeriğini değiştirmek için yapabileceğimiz hiçbir şey yok
Şimdi referansı değiştirmeye çalışalım
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)
Çıktı:
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
Yine, the_string
parametre değere göre iletildiğinden, ona yeni bir dize atamanın, yöntemin dışındaki kodun görebileceği bir etkisi yoktu. the_string
Bir kopyası olan outer_string
referans ve biz vardı the_string
yeni bir dizeye noktası, ama değiştirmek için hiçbir yolu yoktu outer_string
sivri.
Umarım bu biraz şeyleri temizler.
DÜZENLE: Bunun @David'in aslında "Değişkeni gerçek referansla geçmek için yapabileceğim bir şey var mı?" Bunun üzerinde çalışalım.
Bunu nasıl hallederiz?
@ Andrea'nın cevabının gösterdiği gibi, yeni değeri geri verebilirsiniz. Bu, işlerin aktarılma şeklini değiştirmez, ancak istediğiniz bilgileri geri almanıza izin verir:
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)
Bir dönüş değeri kullanmaktan gerçekten kaçınmak istiyorsanız, değerinizi korumak ve onu işleve aktarmak veya liste gibi mevcut bir sınıfı kullanmak için bir sınıf oluşturabilirsiniz:
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])
Bu biraz hantal gibi görünse de.