Kaç Tane Argüman Geleceğini Bilmediğinde
Çoğu fonksiyon sabit sayıda parametre alır. Ama arada bir daha esnek bir şey gerekir — herhangi sayıda mesaj alan bir logger, aldığı her şeyi başka bir fonksiyona ileten bir wrapper fonksiyon, çağıranın hangi seçenekleri kullanacağını tam bilmeden yapılandırma kabul eden bir çizim fonksiyonu.
Python bunu parametre listesindeki iki özel işaretle halleder: *args ve **kwargs.
*args Konumsal Argümanları Toplar
Tek bir yıldız şu demektir: "fazladan gelen tüm konumsal argümanları bir tuple içinde paketle":
Fonksiyonun içinde args, sıradan bir tuple'dır. Üzerinde döngü kurabilir, indeksleyebilir, len() fonksiyonuna geçirebilir ya da dilimleyebilirsin.
*args genellikle isimli parametrelerle birlikte görünür:
first ilk argümanı alır; *rest ondan sonraki her şeyi bir tuple'a paketler.
**kwargs Anahtar Kelime Argümanlarını Toplar
İki yıldız, anahtar kelime argümanları için aynısını yapar ve onları bir dict içine paketler:
describe içinde kwargs, sıradan bir dict'tir. Anahtarlar, string olarak anahtar kelime isimleridir.
İkisini Birlikte Kullanmak
İkisini aynı fonksiyonda kullanabilirsin. Gelenek, *args'ı **kwargs'tan önce yazmaktır:
Tam parametre sırası, baştan sona şöyledir:
- Normal konumsal parametreler (zorunlu veya varsayılanlı).
*args.- Yalnızca anahtar kelime parametreleri (
*args'tan sonra gelen her şeyin anahtar kelimeyle geçirilmesi gerekir). **kwargs.
title ilk konumsalı yakalar. Kalan konumsallar tags içine gider. draft'ın anahtar kelime olarak geçirilmesi gerekir (çünkü *tags'tan sonra geliyor). Diğer tüm anahtar kelime argümanları metadata içine düşer.
Çağrı Yerinde * ve ** ile Açma
Yıldızlar bir de ters yönde çalışır — bir diziyi ya da dict'i bir çağrının argümanlarına yayarlar:
Bu, argüman iletmek için inanılmaz kullanışlıdır:
wrapped, log'un hangi argümanları beklediğini bilmek zorunda değil. Her şeyi toplayıp olduğu gibi iletir. Bu kalıp, decorator'larda (daha ileri bir konu) ve wrapper fonksiyonlarda sürekli karşımıza çıkar.
*args ve **kwargs'ın Yanlış Tercih Olduğu Yerler
İnsan kolayca heyecana kapılıp her yerde kullanabilir. İki uyarı:
Fonksiyonun ne beklediğini gizlerler
Kodunda her fonksiyon def f(*args, **kwargs) ise, çağıran tarafın hangi argümanların geçerli olduğundan haberi olmaz. Mümkün olduğunca isimli parametreleri kullan; *args/**kwargs sadece gerçekten değişken sayıda girdisi olan veya saf iletim yapan durumları taşısın.
Hata mesajları belirsizleşir
Yanlış yazılmış bir anahtar kelime adı, çağrı yerinde anında bir "unexpected keyword argument" hatası vermek yerine fonksiyonun derinliklerinde sessiz bir None'a ya da KeyError'a dönüşür. İsimli parametreler çok daha iyi geri bildirim verir.
Kural olarak: varsayılanda isimli parametreleri tercih et; *args/**kwargs'a ancak fonksiyon gerçekten esnekse veya başka bir çağrılabilire argüman iletiyorsa uzan.
Küçük Pratik Bir Örnek
Üçüncü parti bir fonksiyonu birkaç varsayılanla saran, çizim tarzı bir yardımcı:
*values sayesinde çağıranlar istediği kadar öğe geçebilir; **style ise her seçeneğin isimli parametre olmasını zorunlu kılmadan fazladan yapılandırmayı yutar. İçeride hangi anahtarların style'dan okunduğu açık olduğu için esnek ama belirsiz değil.
Özet
*args, fazladan gelen konumsal argümanları bir tuple'a paketler.**kwargs, fazladan gelen anahtar kelime argümanlarını bir dict'e paketler.- Çağrı yerinde
*seqve**dictters yönde açar. - Parametreler şu sırayla görünmelidir: normal →
*args→ yalnızca anahtar kelime →**kwargs. - Fazla kullanma — isimli parametreleri kullanabildiğin yerde daha nettir.
Sırada: lambda — satır içi yazılan küçük, tek kullanımlık fonksiyonlar.
Sıkça Sorulan Sorular
Python'da *args nedir?
*args, fazladan gelen konumsal argümanları bir tuple içinde toplar. def f(*args): şeklinde tanımladığında f(1, 2, 3) çağrısında args, (1, 2, 3) olarak gelir. args ismi bir gelenektir — istediğini yazabilirsin ama herkes *args kullanır.
Python'da **kwargs nedir?
**kwargs, fazladan gelen anahtar kelime argümanlarını bir dict içinde toplar. def f(**kwargs): tanımıyla f(name='Ada', age=30) çağrısında kwargs, {'name': 'Ada', 'age': 30} olarak gelir. *args ve **kwargs birlikte bir fonksiyonun herhangi bir argüman kombinasyonunu kabul etmesini sağlar.
Bunları illa args ve kwargs diye mi adlandırmam gerek?
Hayır, isim değil yıldızlar önemli. *values ve **options da aynı şekilde çalışır. Ama args ve kwargs, Python kodunda neredeyse evrensel bir gelenektir — daha açıklayıcı bir isim seçmek için belirli bir sebebin yoksa bu ikiliye bağlı kal.