2.15. Argümanlar¶
Bir fonksiyon birkaç şekilde çağrılabilir ve parametreleri birkaç biçimde bildirilebilir. Kombinasyonlar ilk başta göz korkutucu görünür; üç ya da dört kalıp pratikte neredeyse her şeyi kapsar.
2.15.1. Konumsal ve anahtar kelimeli argümanlar¶
En basit çağrı argümanları konuma göre geçirir – ilk değer ilk parametreye, ikincisi ikinciye gider, vb.:
def rect(x, y, w, h):
return (x, y, w, h)
rect(10, 20, 100, 50)
Aynı çağrı, her parametreyi açıkça adlandırarak argümanları anahtar kelimeye göre geçirebilir:
rect(x=10, y=20, w=100, h=50)
Anahtar kelimeli argümanlar sıradan bağımsızdır ve daha fazla yazma pahasına çağrıları kendi kendini belgeler hale getirir. Konumsal ve anahtar kelimeli argümanlar tek bir çağrıda karışabilir, ancak her konumsal argüman herhangi bir anahtar kelimeden önce gelmelidir:
rect(10, 20, w=100, h=50) # OK
rect(x=10, 20, 100, 50) # SyntaxError
2.15.2. Varsayılan değerler¶
Bir parametre, çağıran taraf bir değer sağlamadığında kullanılacak bir varsayılan değer bildirebilir:
def greet(name, greeting="hello"):
print(greeting, name)
greet("Alice") # hello Alice
greet("Alice", "hi") # hi Alice
greet("Alice", greeting="hey") # hey Alice
Varsayılan değeri olan parametreler def satırında, varsayılanı olmayan parametrelerden sonra gelmelidir.
Uyarı
Varsayılan değerler her çağrıda değil, def çalıştığında bir kez değerlendirilir. Değişebilir bir varsayılan ([], {}) kullanmak, aynı nesnenin varsayılanı alan her çağrı arasında paylaşılmasına neden olur. Bunun yerine bir nöbetçi (sentinel) olarak None kullanın:
def append_to(item, target=None):
if target is None:
target = []
target.append(item)
return target
2.15.3. Değişken uzunluk: *args ve **kwargs¶
Önüne * eklenen bir parametre, artakalan tüm konumsal argümanları bir tuple içinde toplar. Önüne ** eklenen bir parametre, artakalan tüm anahtar kelimeli argümanları bir dict içinde toplar. Geleneksel adlar args ve kwargs‘tır, ancak herhangi bir tanımlayıcı işe yarar:
def report(label, *values, **options):
print(label, values, options)
report("temps", 21, 22, 23, unit="C", precision=1)
Çıktı:
temps (21, 22, 23) {'unit': 'C', 'precision': 1}
Bir fonksiyonun nadiren her ikisine de ihtiyacı olur. En yaygın kullanım, argümanları bir sarmalayıcıdan iç bir çağrıya iletmektir:
def log_and_call(func, *args, **kwargs):
print("calling", func.__name__)
return func(*args, **kwargs)
Çağrı tarafındaki ayna görüntüsü sözdizimi, bir iterable’ı konumsal argümanlara (*) veya bir dict nesnesini anahtar kelimeli argümanlara (**) açar:
point = (10, 20, 100, 50)
rect(*point) # same as rect(10, 20, 100, 50)
kwargs = {"x": 10, "y": 20, "w": 100, "h": 50}
rect(**kwargs) # same as rect(x=10, y=20, ...)
2.15.4. Yalnızca anahtar kelimeli parametreler¶
Parametre listesinde tek başına duran bir * (bir ada bağlı değil), kendisinden sonra gelen her parametreyi yalnızca anahtar kelimeli olarak işaretler – çağıran taraf adı kullanmak zorundadır:
def crop(buffer, *, x, y, w, h):
...
crop(buffer, x=0, y=0, w=100, h=100) # OK
crop(buffer, 0, 0, 100, 100) # TypeError
Bunu, çağrı tarafındaki çıplak bir değerin kendiliğinden açıklayıcı olmayacağı boolean bayraklar ve diğer argümanlar için kullanın.