Nasıl referans bir değişken geçtim mi?
Python belgelerine parametreleri referans veya değer tarafından geçirilen olup olmadığı konusunda açık görünüyor, ve aşağıdaki kodu değişmeden değer üretir 'Orijinal'
class PassByReference:
def __init__(self):
self.variable = 'Original'
self.Change(self.variable)
print self.variable
def Change(self, var):
var = 'Changed'
Gerçek referans ile değişken geçmek için yapabileceğim bir şey var mı?
CEVAP
Değişkenler passed by assignment. Bunun arkasındaki gerekçe, iki yönlüdür:
- parametre geçti aslındabaşvuru(ama referans değeri tarafından geçirilen) bir nesne
- bazı veri türlerini değiştirilebilir, ama diğerleri değil
Yani:
Eğer başarılı olursakesilebilirnesnesine bir yöntem, bu yöntemi alır bir başvuru için, aynı nesne ve sen-ebilmek değişmek senin kalp zevk, ama eğer yeniden bağlayın, başvuru yöntemi, dış kapsam olacak hakkında hiçbir şey bilmiyorum, ve sonra senin işin bitti, dış referans olacak hala bir noktada orijinal nesne.
Eğer başarılı olursadeğişmezbir yöntem, nesne, hala dış referans bağlamanız yok, ve hatta nesne mutasyona edebilirsiniz.
Bunu daha açık hale getirmek için, hadi bazı örnekler var.
Liste - değişken bir tip
Hadi bir yönteme geçildi listesini değiştirmek için deneyin:
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
Çıkış:
before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']
Parametre geçirilen outer_list
bir kopyasını değil, bir başvuru olduğu, mutasyona listesi yöntemlerini değiştirmek için kullanın ve değişiklikleri dış kapsam yansıması olabilir.
Şimdi bir parametre olarak iletilen başvuru değiştirmeye çalıştığınızda ne olur: 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
Çıkış:
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']
the_list
parametre değeri tarafından kabul edilmesinden bu yana, yeni bir liste atama yöntemi dışında kod görebiliyordu hiçbir etkisi olmadı. the_list
outer_list
referans oldu, ve yeni bir liste için the_list
noktası vardı, ama outer_list
sivri yerleri değiştirmek için bir yolu yoktu.
Dize değişmez bir tip
Değişmez, dize içeriğini değiştirmek için yapabileceğimiz hiçbir şey yok
Şimdi, diyelim ki başvuru değiştirmeyi deneyin
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
Çıkış:
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
the_string
parametre değeri tarafından kabul edilmesinden bu yana, yeniden, yeni bir dize atama yöntemi dışında kod görebiliyordu hiçbir etkisi olmadı. the_string
outer_string
referans oldu, ve yeni bir dizeye the_string
noktası vardı, ama outer_string
sivri yerleri değiştirmek için bir yolu yoktu.
Bu işler biraz temizler umarım.
DÜZENLEME:Bu @David başlangıçta sorulan soruya cevap tutmaz oldu, "gerçek referans ile değişken geçmek için yapabileceğim bir şey var mı?". - O konuda çalışalım.
Bunu nasıl halledeceğiz?
@Andrea cevabı gösterdiği gibi, yeni değeri döndürür. Bu şeyler geçti, ama geri dışarı istediğiniz bilgileri gidelim mi değişmez:
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)
Eğer gerçekten bir dönüş değeri kullanmaktan kaçınmak istiyorsa, değeri ve işlevi haline geçmesi veya kullanım varolan bir sınıf için bir sınıf, bir liste gibi 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.
Nasıl doğru ActionScript 3 SOAP web se...
Nasıl komisyon bir görev için komut sa...
Nasıl değişken olup olmadığını belirle...
Nasıl Düzenli İfade, JavaScript için b...
Tarayıcı kapsamı değişken $erişmeye�...