Python'un fonksiyonlarda argümanları nasıl ilettiğini anlamak, veri değişikliklerini önlemek ve kod tasarımını doğru bir şekilde yapmak için son derece önemlidir.
C veya Java gibi geleneksel programlama dillerinde, değerle iletim (copy by value) veya referansla iletim (copy by reference) kullanılır. Ancak Python'da farklı bir model vardır — call by object reference (bazen "call by sharing" olarak adlandırılır).
Pek çok geliştirici, Python'un her zaman ya referansla ya da değerle argümanları ilettiğini düşünmektedir. Bu, değiştirilebilir nesnelerin, çağrılan kodda beklenmedik bir şekilde değiştirilmesine neden olan durumlara yol açar.
Python'da fonksiyonun parametrelerinin değerleri, fonksiyona iletilen nesnelere referanslardır. Bu şunu ifade eder:
Örnek:
# list - değiştirilebilir (mutable) def add_item(lst): lst.append(42) my_list = [1, 2, 3] add_item(my_list) print(my_list) # [1, 2, 3, 42] # int - değiştirilemez (immutable) def add_num(x): x = x + 1 num = 10 add_num(num) print(num) # 10
Anahtar Özellikler:
Python'da argümanlar her zaman referansla mı iletilir?
Hayır, Python'da nesnelere referanslar iletilir ve nesnenin nasıl davrandığı, değiştirilebilir olup olmadığına bağlıdır. Değiştirilemez bir nesne herhangi bir değişiklikte yeni bir nesne oluşturacaktır.
Fonksiyonda değiştirilebilir bir argümanı yeniden atayabilir miyim ve bu dış nesneyi etkileyebilir mi?
Hayır. Eğer fonksiyon içinde bir parametreye yeni bir değer atarsanız, dış nesne değişmeyecek - sadece yerel bir referansı değiştirirsiniz.
Örnek:
def reassign_list(lst): lst = [99, 100] my_list = [1, 2, 3] reassign_list(my_list) print(my_list) # [1, 2, 3]
Varsayılan olarak bir list alan bir fonksiyon, ikinci kez çağrıldığında neden garip çalışabilir?
Çünkü varsayılan değer bir kez oluşturulur — fonksiyon tanımlandığında ve eğer bu değiştirilirse (örneğin, bir öğe eklemek), tüm sonraki çağrılar için değişecektir.
def add_element(x, cache=[]): cache.append(x) return cache print(add_element(1)) # [1] print(add_element(2)) # [1, 2]
Bir programcı bir listeyi bir fonksiyona geçiriyor ve orijinal listesinin değişmeyeceğini bekliyor ama fonksiyon bir öğe ekliyor.
Artıları:
Eksileri:
Bir programcı, geri dönecek bir şey lazım olduğunda, fonksiyon içinde listeyi açıkça kopyalar ama orijinalini değiştirmemek için:
def process_data(data): data = data.copy() # veya list(data) # kopya ile güvenli çalışma data.append('rapor') return data
Artıları:
Eksileri: