Fonksiyonlar, kapsam ve modüller
C’de programı fonksiyonlara bölmeyi öğrendiniz. Nesne tabanlı programlamada da bu beceriye ihtiyacınız olacak, çünkü ileride yazacağımız sınıfların içindeki metotlar da birer fonksiyondur. Bu hafta Python’da fonksiyon yazacak ve kodu dosyalara böleceğiz. Örneklerin çoğu bir not programından: ortalamayı hesaplayan, geçme sınırına bakan ve listeye not ekleyen fonksiyonlar yazacak, sonra bunları ayrı bir dosyaya taşıyacağız. Söz dizimi C’ye yakın. Bölümde en çok C’den farklı davranan yerlerde duracağız: fonksiyonun dışındaki bir ada atama, fonksiyona verilen listenin değişmesi ve parametrenin varsayılan değeri.
Bu sayfadaki kod hücreleri kendiliğinden çalışmaz. Her hücrede önce çıktıyı tahmin edin, sonra Run Code düğmesine basın. Kodu değiştirip yeniden çalıştırabilir, Start Over ile ilk hâline döndürebilirsiniz.
Bu bölümün kapsamı
print()ilereturnfarkı ve örtükNone- Varsayılan parametre, konumsal argüman ve anahtar kelime argümanı
- Yerel ad ile dış kapsamdaki ad,
UnboundLocalErrorveglobal - Değiştirilebilir parametrede yan etki,
intparametrenin yeniden bağlanması - Değiştirilebilir (mutable) varsayılan değer tuzağı ve
Nonenöbetçisi - Docstring ile davranış sözleşmesi
importile modül kullanmak ve__name__ == "__main__"kalıbının ne işe yaradığı
- Birden çok değer döndürme (
return low, high) - Değişken sayıda argüman (
*args,**kwargs) - Lambda ifadeleri ve closure
- Paket yayımlama (
pip install, PyPI)
Bu başlıklar konunun devamıdır. İleride karşınıza çıkar, ama bu derste ezberlemeniz beklenmiyor.
Fonksiyon tanımlamak: def
Ortalamayı programın birkaç yerinde hesaplayacaksanız bu kodu bir fonksiyona koyarsınız. Python’da fonksiyon def ile tanımlanır. C’deki gibi dönüş türü ve parametre türleri yazılmaz. def satırı : ile biter, gövdeyi girinti belirler. Hücre ne yazar: 80 mi, 80.0 mı?
first ve second parametrelerdir, çağrıdaki 70 ve 90 argümanlardır. 1. haftada gördüğünüz gibi / her zaman float döndürür.
C’de bir fonksiyonu çağırmadan önce onu tanımlamanız ya da prototipini yazmanız gerekirdi. Python’da prototip yoktur, ama def satırı fonksiyonu çağıran satırdan önce çalışmış olmalıdır. Python dosyayı yukarıdan aşağı çalıştırır. Bu yüzden fonksiyon tanımları çoğu zaman dosyanın başına, onları çağıran satırların üstüne yazılır.
Fonksiyonun adı ne yaptığını söylemeli. calculate_average (ortalama hesapla) adını okuyan, gövdeye bakmadan işi anlar. process ya da do_it gibi adlar bunu söylemez.
print() ekrana yazar, return çağırana verir
C’de ortalamayı printf ile yazdıran void bir fonksiyonun sonucunu bir değişkene atamaya kalkarsanız derleyici hata verirdi. Python’da bu atama hata vermez. Aşağıdaki iki fonksiyondan biri sonucu yazdırıyor, öteki döndürüyor. Ekranda kaç satır görünür? first: satırında ne yazar?
return içermeyen bir fonksiyonun çağrısı None verir. 3. haftada .sort() çağrısının döndürdüğü None da buydu: Python’da “değer yok” anlamına gelen özel değer. Ekrana yazılan bir sayıyı programın geri kalanında kullanamazsınız. Sonucu başka bir hesapta kullanacaksanız return yazın.
first = show_square(5) satırı çalışırken gövdedeki print() ekrana 25 yazar. Fonksiyon bir değer döndürmediği için first adı None’a bağlanır ve first: None görünür. get_square ise ekrana bir şey yazmaz, 25 değerini döndürür. Son satır second: 25 olur. Ekranda toplam üç satır vardır.
C’de olduğu gibi return çalışınca fonksiyon orada biter, altındaki satırlar çalışmaz. Bir fonksiyonda birden çok return olabilir. Aşağıdaki fonksiyon notu harfe çeviriyor. letter_grade(95) ve letter_grade(40) ne döndürür? 95 için kaç if satırı çalışır?
95 için ilk koşul doğrudur, return "A" çalışır ve fonksiyon biter. İkinci if satırına hiç gelinmez. 40 için iki koşul da yanlıştır, son satırdaki return "F" çalışır. Ekranda A ve F görünür.
Varsayılan parametre ve anahtar kelime argümanı
C’de bir parametreye varsayılan değer veremezdiniz: geçme sınırını her çağrıda yazar ya da iki ayrı fonksiyon tanımlardınız. Python’da parametreye tanımda bir değer verebilirsiniz. Üç satır ne yazar?
limit=50 bir varsayılan değerdir: çağrıda limit verilmezse 50 kullanılır. İlk iki çağrıdaki argümanlar konumsal argümandır, yani sırasına göre parametreye gider: ilk değer score’a, ikincisi limit’e. Üçüncü çağrıdaki score=70 ve limit=60 ise anahtar kelime argümanıdır: değer parametrenin adıyla birlikte verilir. Birden çok isteğe bağlı parametre olduğunda hangi değerin hangi parametreye gittiği böylece çağrı satırından okunur.
İki biçimi aynı çağrıda birlikte kullanabilirsiniz: is_successful(70, limit=60). Ama iki sıra kuralı var. Çağrıda konumsal argümanlar önce, anahtar kelime argümanları sonra gelir. Tanımda da varsayılan değeri olan parametreler, varsayılanı olmayanlardan sonra yazılır. Aşağıdaki iki satırın ikisi de çalışmadan SyntaxError verir:
is_successful(score=70, 60) # konumsal argüman, anahtar kelime argümanından sonra
def is_successful(limit=50, score): # varsayılanı olmayan parametre, varsayılanlıdan sonra
return score >= limitYerel kapsam, global ad ve UnboundLocalError
Kaç öğrencinin ortalamasının hesaplandığını saymak için C’de çoğu zaman global bir değişken tutar, fonksiyonun içinde count++ yazardınız. Python’da da fonksiyon dışarıdaki bir adı okuyabilir. Hücre ne yazar? Son satırın başındaki # işaretini silip yeniden çalıştırırsanız ne olur?
tax fonksiyonun içinde oluşturulduğu için yerel bir addır. C’deki yerel değişkenler gibi yalnızca o fonksiyonun içinde kullanılabilir, dışarıdan okumaya çalışırsanız NameError alırsınız. rate ise fonksiyonun dışında tanımlıdır ve fonksiyon onu dış kapsamdan (scope) okur. Kapsam, bir adın programın hangi bölümünde geçerli olduğudur.
Okumak sorun çıkarmıyor. Şimdi sayacı fonksiyonun içinde artıralım. increase() çağrılınca ilk satırdaki print(count) ne yazar?
Python bir adın yerel olup olmadığına satır satır değil, fonksiyonun tamamına bakarak karar verir. Gövdede count’a atama varsa count fonksiyonun her satırında yerel sayılır, atamadan önceki satırlarda da. print satırı çalıştığında bu yerel count’a henüz değer verilmemiştir. Python bu duruma UnboundLocalError der.
Dıştaki count’u değiştirmek istiyorsanız bunu global ile açıkça söylemeniz gerekir:
count = 10
def increase():
global count
count += 1Ama her sorunu global ile çözerseniz hangi fonksiyonun hangi değişkeni değiştirdiğini izlemek zorlaşır. Bu derste mümkün olduğunca girdiyi parametreyle alıp sonucu return ile vereceğiz: count = increase(count) gibi bir çağrıda fonksiyon yeni değeri döndürür, atamayı çağıran yapar.
Değiştirilebilir parametre ve yan etki
C’de not dizisine eleman ekleyen bir fonksiyona diziyi ve eleman sayısının adresini verirdiniz. Dizi fonksiyona adresiyle gittiği için fonksiyon asıl diziyi değiştirirdi. Python’da listeyi fonksiyona verince ne olur? add_score hiçbir şey döndürmüyor. numbers değişir mi?
Çağrı sırasında scores parametresi, çağıranın verdiği listenin kendisine bağlanır. Python listeyi kendiliğinden kopyalamaz. append() bu ortak listeyi değiştirdiği için numbers da yeni içeriği gösterir. 3. haftadaki second = first deneyiyle aynı durum: iki ad, bir liste. Fonksiyonun değer döndürmek dışında çağıranın da gördüğü bir şeyi değiştirmesine yan etki (side effect) denir.
C’de int parametre kopyalanırdı ve fonksiyondaki değişiklik dışarıya yansımazdı. Python’da fonksiyona bir sayı verelim. add_one gövdesinde number += 1 yazıyor. Son satır ne yazar?
Son satır 5 yazar. Sonuç C’deki gibi, ama nedeni farklı. int değiştirilemez bir nesnedir. number += 1 o nesneyi değiştirmez, yerel number adını 6 değerindeki yeni bir nesneye bağlar. total ise 5’e bağlı kalır. Bir adı başka bir nesneye bağlamaya 6. haftada ayrıntısıyla döneceğiz.
“Python her şeyi adresle geçirir” diye düşünürseniz add_one örneğini açıklayamazsınız: adres gitseydi total 6 olurdu. Bu derste şöyle düşüneceğiz: her ad bir nesneye bağlanır, fonksiyon çağrılınca parametre adı da verilen nesneye bağlanır. Değiştirilebilir bir nesne yerinde değiştirilirse, o nesneye bağlı bütün adlar değişikliği görür. Parametre adını başka bir nesneye bağlamak ise çağıranı etkilemez.
Yan etki bazen istenir, bazen beklenmedik bir hataya yol açar. Çağıranın listesi değişmesin istiyorsak yeni bir liste döndürürüz. with_score iki listeyi + ile birleştiriyor. İki satır ne yazar?
İki liste + ile birleştirilince yeni bir liste oluşur, numbers olduğu gibi kalır. Peki gövdede scores += [value] yazsaydık? int için += adı yeni bir nesneye bağlıyordu. Listede de öyle mi?
[70, 80, 90] yazar. Listede += yeni liste oluşturmaz, aynı listeyi yerinde uzatır, tıpkı extend() gibi. numbers da aynı listeye bağlı olduğu için değişikliği görür. += değiştirilemez bir nesnede (int, str) yeni nesne oluşturur, listede ise var olan listeyi değiştirir. Çağıranın listesini korumak istiyorsanız scores + [value] yazıp sonucu döndürün.
Fonksiyonu çağıran kişi, listesinin değişip değişmeyeceğini nereden bilir? Bunu fonksiyonun sözleşmesi söyler: fonksiyonun ne aldığını, ne döndürdüğünü ve neyi değiştirdiğini anlatan tanım. Sözleşmeyi koda yazmanın yolunu birazdan göreceğiz.
Değiştirilebilir varsayılan değer tuzağı
Varsayılan değer bir liste olursa ne olur? Aşağıdaki fonksiyonda liste verilmezse items için varsayılan [] kullanılır. İki çağrı ne yazar?
Varsayılan [] her çağrıda yeniden oluşturulmaz. Python onu def satırı çalışırken bir kez oluşturur. Liste verilmeyen bütün çağrılar bu tek listeyi kullanır. C’deki yerel dizi her çağrıda yeniden kurulurdu. Burada öyle olmaz.
İlk çağrı varsayılan listeye "A" ekler ve ['A'] yazar. İkinci çağrı yeni bir liste almaz, aynı listeye "B" ekler ve ['A', 'B'] yazar. Bir önceki başlıktaki durumun aynısı: iki çağrı, bir liste.
Sorunu önlemek için şu kalıp kullanılır. Bu kez iki çağrı ne yazar?
Burada None, “çağıran liste vermedi” anlamına gelen bir işarettir. Bu işi gören değere nöbetçi (sentinel) denir. Liste artık gövdede oluşturulduğu için liste verilmeyen her çağrı yeni bir boş listeyle başlar. Çağıran kendi listesini verirse fonksiyon o listeye ekler.
7. haftada sınıflarla çalışırken benzer bir sorunla karşılaşacağız. Onun nedeni de aynı: değiştirilebilir bir nesneyi farkında olmadan birden çok yerde ortak kullanmak.
Docstring: davranış sözleşmesini koda yazmak
C’de fonksiyonun ne yaptığını prototipin üstüne yazdığınız bir yorumla anlatırdınız. Python’da bu açıklamanın belli bir yeri var. Docstring, fonksiyon tanımının hemen altına üç tırnak içinde yazılan açıklama metnidir. Kısa bir docstring, fonksiyonun ne beklediğini, ne döndürdüğünü, varsa önemli yan etkilerini ve hangi durumda hata verdiğini yazar. add_score listeyi değiştiriyordu. Bunu docstring’e yazalım ve help() ile okuyalım:
help() docstring’i fonksiyonun adı ve parametreleriyle birlikte ekranda gösterir. Fonksiyonu kullanacak kişi gövdeyi okumadan listesinin değişeceğini öğrenir.
Hata koşulu da sözleşmenin parçasıdır:
def calculate_discount(price, rate=0.10):
"""Fiyatın indirimli tutarını döndürür.
price negatifse ValueError yükseltir. Girdileri değiştirmez.
"""
if price < 0:
raise ValueError("Fiyat negatif olamaz")
return price * (1 - rate)Buradaki raise satırı, fiyat negatifse hatayı çağırana bildirir. raise, try ve except arasındaki ilişkiyi 5. haftada ayrıntısıyla göreceğiz.
Her fonksiyon tek bir iş yapsın
Bir fonksiyon hem kullanıcıdan fiyatı alır, hem doğrular, hem hesaplar, hem de sonucu yazdırırsa onu denemek ve değiştirmek zorlaşır. Fiyatı her denemede klavyeden girmeniz gerekir, sonucu da ancak ekrandan okursunuz.
calculate_discount yalnızca indirimi hesaplar ve fiyatın negatif olmadığını denetler. Fiyatı kullanıcıdan alan input() satırı da sonucu yazdıran print() satırı da başka bir yerde durur. Böylece calculate_discount(100) çağrısının sonucunu bir satırda deneyebilirsiniz.
Modüller: kodu dosyalara ayırmak
C’de bir fonksiyonu başka bir dosyada kullanmak için prototipini .h dosyasına yazar, onu #include ile ekler ve iki .c dosyasını birlikte derlerdiniz. Python’da başlık dosyası yoktur. Her .py dosyası bir modüldür: başka bir dosya onun içindeki fonksiyonları import ile içe aktarıp çağırabilir.
Python’la birlikte gelen modüller de aynı yolla kullanılır. math modülü matematik fonksiyonlarını tutar. Hücre ne yazar: 4 mü, 4.0 mı?
import math modülün kendisini alır, fonksiyona math.sqrt diye modülün adıyla ulaşırsınız. from math import sqrt ise yalnız sqrt adını alır, fonksiyonu doğrudan sqrt(16) diye çağırırsınız.
Kendi yazdığınız bir dosya da aynı biçimde modül olur. Örneğin:
# pricing.py
def final_price(price, tax_rate):
return price * (1 + tax_rate)Aynı klasördeki app.py dosyasında:
from pricing import final_price
print(final_price(100, 0.20))from pricing import final_price satırı aynı klasördeki pricing.py dosyasını bulur, çalıştırır ve içindeki final_price fonksiyonunu app.py içinde kullanılabilir hâle getirir. import pricing yazarsanız fonksiyonu pricing.final_price(100, 0.20) diye çağırırsınız.
Kod hücresinde ikinci bir .py dosyası açıp düzenleyemediğiniz için bu örneği kendi bilgisayarınızda deneyin. 1. haftada kurduğunuz VS Code’da bir klasör açın, iki dosyayı bu klasöre kaydedin ve app.py dosyasını çalıştırın. Windows’ta terminale py app.py yazabilirsiniz. Programı çalıştırdıktan sonra klasörde __pycache__ adlı bir klasör belirir. Python, içe aktardığı modülün bytecode’unu (1. haftada gördüğümüz ara kodu) orada saklar. Bu klasörü silebilirsiniz, Python gerektiğinde yeniden oluşturur.
__name__ == "__main__" ne işe yarar?
C’de fonksiyonları ayrı bir .c dosyasına taşıdığınızda o dosyaya main() yazmazdınız, çünkü bir programda tek bir main() bulunur. Python’da bir modül ilk kez içe aktarıldığında modülün kodu baştan sona bir kez çalışır: def satırları fonksiyonları tanımlar, girintisiz bir print() satırı da ekrana yazar. Aynı programda modülü ikinci kez içe aktarmak onu yeniden çalıştırmaz. pricing.py dosyasına hiçbir fonksiyonun içinde olmayan, girintisiz bir print(final_price(100, 0.20)) deneme satırı yazarsanız, bu satır modülü içe aktaran her programda da çalışır.
Python her modülde __name__ adında bir değişken tutar. Bir dosya doğrudan çalıştırıldığında __name__ değeri "__main__" olur. Başka bir dosyadan içe aktarıldığında ise modülün adını alır (örneğin "pricing"). Deneme satırını bu değişkene bakarak yalnız dosya doğrudan çalıştırıldığında çalıştırabilirsiniz:
# pricing.py
def final_price(price, tax_rate):
return price * (1 + tax_rate)
def main():
print(final_price(100, 0.20))
if __name__ == "__main__":
main()Bu kalıba kısaca main guard denir. py pricing.py yazınca __name__ değeri "__main__" olur ve deneme satırı çalışır. app.py ise final_price fonksiyonunu alır, ama main() çalışmaz. 13. haftada birkaç dosyadan oluşan bir OOP programında bu kalıbı yeniden kullanacağız.
C ile Python yan yana
Bu haftaki işlerin C’deki ve Python’daki karşılıkları:
| İş | C’de | Python’da | Dikkat |
|---|---|---|---|
| Ortalamayı hesaplayıp başka hesapta kullanmak | Fonksiyon yazar, sonucu return ile döndürürsünüz |
def calculate_average(first, second): ve return |
Yalnız print() eden fonksiyonun çağrısı None verir |
| Sınırı çoğu derste 50, bazılarında 60 almak | Varsayılan değer yoktur, sınırı her çağrıda yazarsınız | def is_successful(score, limit=50): |
Varsayılan değer olarak liste vermeyin, None nöbetçisini kullanın |
| Hesaplanan ortalamaları saymak | Global bir sayaç tutar, fonksiyonda count++ yazarsınız |
Sayıyı parametreyle alıp yeni değeri return ile vermek ya da global count |
global yazmadan dıştaki ada atama yapmak UnboundLocalError verir |
| Not listesine not eklemek | Diziyi ve eleman sayısının adresini verirsiniz, fonksiyon asıl diziyi değiştirir | Fonksiyonda scores.append(value) |
Python listeyi kopyalamaz, çağıranın listesi değişir. Bunu docstring’e yazın |
| Fonksiyonları ayrı dosyada kullanmak | Prototipi .h, gövdeyi .c dosyasına yazar, #include eder ve birlikte derlersiniz |
pricing.py ve from pricing import final_price |
İlk import modülün kodunu baştan sona çalıştırır. Deneme kodunu if __name__ == "__main__": altına yazın |
return iki dilde de aynı işi görür. Varsayılan değer C’de yoktu, Python’da var. Son üç satırda ise C alışkanlığı sizi yanıltabilir. C’de global değişkeni fonksiyonun içinden doğrudan değiştirebilirdiniz, Python bunun için global ister. C’de dizi fonksiyona adresiyle, int ise kopya olarak giderdi. Python’da her parametre çağıranın verdiği nesneye bağlanır. Listenin değişip sayının değişmemesi, listenin değiştirilebilir, int’in değiştirilemez olmasından gelir. C’deki #include başlık dosyasındaki bildirimleri ekler, Python’daki import ise modülün kodunu çalıştırır. Sonraki haftalarda fonksiyonlara listelerin yerine kendi yazdığımız nesneleri vereceğiz. Listeler için geçerli olan kural onlar için de geçerli: fonksiyon nesneyi değiştirirse çağıran da değişikliği görür.
Alıştırma: return ekle
clamp_zero negatif bir değer için 0, öteki değerler için değerin kendisini döndürsün. Boşlukları doldurun.
Beklenen çıktı 0 ve 8’dir.
def clamp_zero(value):
if value < 0:
return 0
return valueAlıştırma: Yan etkiyi tahmin et
Önce çıktıyı tahmin edin, sonra hücreyi çalıştırın.
- Çıktıyı neden böyle tahmin ettiniz? Hangi satır listeyi değiştiriyor?
- Fonksiyonun çağıranın listesini değiştirmesini istemeseydik hangi yaklaşımı kullanabilirdik?
- Fonksiyonun listeyi değiştirdiği adından anlaşılıyor mu, yoksa bunu docstring’e de yazmak gerekir mi?
['Ayşe', 'Mehmet']yazar.items.pop()satırı,namesile aynı listeye bağlı olanitemsüzerinden listenin son elemanını çıkarır.- Yeni bir liste döndürmek:
return items[:-1]. Dilim yeni bir liste oluşturur,namesolduğu gibi kalır. Çağıran sonucushorter = remove_last(names)diye alır. - “remove” (çıkar) sözcüğü listenin değiştiğini düşündürür, ama hangi listenin değiştiğini söylemez. Docstring’e “Çağıranın listesini değiştirir, bir değer döndürmez.” yazmak bu soruyu ortadan kaldırır.
Alıştırma: Varsayılan listeyi düzelt
Aşağıdaki collect fonksiyonunu, liste verilmeyen her çağrı yeni bir liste ile başlayacak biçimde düzeltin. None nöbetçisini kullanın. Çağıran bir liste verirse fonksiyon o listeye eklemeye devam etsin.
Düzeltince iki satır [1] ve [2] yazmalı. Buna neden gerek olduğunu kendinize bir cümleyle açıklayın.
def collect(value, values=None):
if values is None:
values = []
values.append(value)
return valuesSıra sizde: Not yardımcı modülü
Kendi bilgisayarınızda aynı klasöre iki dosya kaydedin. grades.py dosyasında şu iki fonksiyonu tanımlayın ve her birine kısa bir docstring ekleyin:
average(scores): not listesinin ortalamasını döndürür. Listenin boş olmadığını varsayabilirsiniz.is_successful(score, limit=50): not sınıra eşit ya da büyükseTruedöndürür.
app.py dosyasında bu fonksiyonları import ile içe aktarın ve birkaç örnek veriyle çağırın. Argümanları hem sırasıyla (konumsal argüman) hem de parametre adıyla (anahtar kelime argümanı) verin. Ardından grades.py dosyasına, dosya doğrudan çalıştırıldığında birkaç örnek sonuç yazdıran bir main() fonksiyonu ve main guard ekleyin.
Çalışır kod görevi: app.py dosyasını Windows’ta py app.py, macOS’ta python3 app.py ile çalıştırın. app.py içine en az üç assert satırı ekleyin. assert satırı bir koşulu denetler: koşul doğruysa hiçbir şey yapmaz, yanlışsa programı AssertionError ile durdurur. Olağan değerleri de sınır değerlerini de deneyin. Örnek:
assert average([70, 80]) == 75
assert is_successful(50)
assert not is_successful(49)
assert not is_successful(55, limit=60)app.py çalışırken grades.py içindeki örnek sonuçlar ekranda görünmemeli. Görünüyorsa main guard’ı denetleyin.
Tek sayfa özet
- Python’da fonksiyon
defile tanımlanır. Parametre ve dönüş türü yazılmaz, gövdeyi girinti belirler. returnsonucu çağırana verir,print()yalnızca ekrana yazar.returniçermeyen fonksiyonun çağrısıNoneverir.returnçalışınca fonksiyon biter.- Varsayılan değeri olan parametre çağrıda yazılmayabilir. Konumsal argüman sırasına göre, anahtar kelime argümanı parametrenin adıyla verilir. Çağrıda konumsal argümanlar önce gelir, tanımda varsayılanı olan parametreler sona yazılır.
- Fonksiyon dıştaki bir adı okuyabilir, ama gövdede o ada atama yaparsa Python adı fonksiyonun her satırında yerel sayar.
UnboundLocalErrorçoğu zaman bundan çıkar. Dıştaki adı değiştirmek içinglobalgerekir, ama yeni değerireturnile vermek daha kolay izlenir. - Fonksiyon çağrılınca parametre adı verilen nesneye bağlanır. Fonksiyon listeyi yerinde değiştirirse (
append,pop,+=) çağıran da değişikliği görür.intgibi değiştirilemez bir değerde+=yalnız yerel adı yeni bir nesneye bağlar. - Varsayılan değer
defsatırı çalışırken bir kez oluşturulur. Liste gerekiyorsa varsayılanıNoneyapın, listeyi gövdede oluşturun. - Docstring, fonksiyonun ne alıp ne döndürdüğünü, neyi değiştirdiğini ve ne zaman hata verdiğini kodun hemen yanında anlatır.
help()onu ekranda gösterir. - Her
.pydosyası bir modüldür. Modül ilk kez içe aktarıldığında kodu baştan sona bir kez çalışır. Deneme koduif __name__ == "__main__":(main guard) altına yazılır.
Bu bölümün kazanımları
Bu bölümü bitiren öğrenci:
print()ilereturnfarkını açıklar vereturniçermeyen bir fonksiyonun çağrısınınNoneverdiğini öngörür.- Varsayılan parametre, konumsal argüman ve anahtar kelime argümanıyla yazılmış bir çağrının sonucunu öngörür.
- Değiştirilebilir varsayılan değer tuzağını tanır ve
Nonenöbetçisiyle önler. - Yerel ad ile dış kapsamdaki adı ayırt eder ve
UnboundLocalErrornedenini açıklar. - Fonksiyona verilen nesnenin çağrıdan sonra değişip değişmeyeceğini öngörür.
- Bir docstring’in fonksiyonun sözleşmesinden neleri yazması gerektiğini açıklar.
import’un modülü nasıl çalıştırdığını ve__name__ == "__main__"kalıbının deneme kodunu neden ayırdığını açıklar.