Fonksiyonlar, kapsam ve modüller
Nesne tabanlı programlama, iyi fonksiyon tasarımının yerine geçmez. Aksine sınıf metotları da fonksiyon mantığı üzerine kurulur. Bu hafta Python’da parametre, dönüş değeri, kapsam ve modül kullanımını hızlı biçimde toparlayacağız; aynı zamanda “tek büyük program” yerine sorumlulukları küçük parçalara ayırma alışkanlığını güçlendireceğiz.
Bu hafta neleri yapabilmelisiniz?
defile fonksiyon tanımlayabilmeli,- parametre ile argüman ayrımını açıklayabilmeli,
returnile sonuç döndürebilmeli,- yerel ve küresel kapsam farkını gözlemleyebilmeli,
- fonksiyona değiştirilebilir nesne verildiğinde yan etkileri fark edebilmeli,
- kendi modülünüzü oluşturup
importedebilmeli, - bir programı anlamlı sorumluluklara göre fonksiyonlara ayırabilmelisiniz.
Fonksiyon: adlandırılmış davranış
first ve second parametrelerdir; çağrıdaki 70 ve 90 argümanlardır.
Fonksiyon adı, “nasıl yapılıyor?” ayrıntısından önce “ne yapıyor?” sorusuna cevap vermelidir. calculate_average bu açıdan process veya do_it gibi belirsiz adlardan daha açıklayıcıdır.
print() ile return aynı şey değildir
show_square ekrana yazar ama sonuç döndürmez; dolayısıyla çağrının değeri None olur. get_square ise değeri çağırana verir ve başka hesaplarda kullanılabilir.

print ile ekrana yazdırma ve return ile çağırana değer döndürme arasındaki fark.Yerel kapsam
tax fonksiyon içinde yereldir. rate dış kapsamdan okunmuştur. Küresel değişken okumak mümkün olsa da iş kurallarını büyük ölçüde küresel duruma bağlamak programı zor izlenir hâle getirir.
Değiştirilebilir parametre ve yan etki
Aşağıdaki örneği çalıştırmadan önce numbers listesinin değişip değişmeyeceğini tahmin edin.
Çağrı sırasında scores parametre adı, çağıranın verdiği aynı liste nesnesine bağlanır. Python listeyi otomatik olarak kopyalamaz. append() bu ortak liste nesnesinin durumunu değiştirdiği için çağıran taraf da yeni içeriği görür. Bu davranış bazen istenen şeydir; bazen de beklenmedik yan etkidir. Fonksiyonun sözleşmesi bunu açık kılmalıdır.
Bu davranışı “Python her şeyi referansla geçirir” biçiminde genellemek yanıltıcı olabilir. Bu derste daha güvenli zihinsel model şudur: adlar nesnelere bağlanır; fonksiyon çağrısında parametre adları da verilen nesnelere bağlanır. Mutable nesne yerinde değiştirilirse bu değişiklik aynı nesneyi gören yerlerden fark edilir.
Alternatif olarak yeni liste döndürebiliriz:
Fonksiyonları sorumluluğa göre ayırmak
Tek bir fonksiyonun aynı anda veri alma, doğrulama, hesaplama, dosyaya yazma ve çıktı üretme görevlerini üstlenmesi test etmeyi ve değiştirmeyi zorlaştırır.
Örneğin:
def calculate_discount(price, rate):
if price < 0:
raise ValueError("Fiyat negatif olamaz")
return price * (1 - rate)Bu fonksiyon yalnızca hesaplama ve temel kuralı üstlenir. Kullanıcıdan veri alma ayrı yerde tutulabilir.
Modüller: kodu dosyalara ayırmak
Bir Python dosyası modül olarak kullanılabilir. Örneğin:
# pricing.py
def final_price(price, tax_rate):
return price * (1 + tax_rate)Başka dosyada:
from pricing import final_price
print(final_price(100, 0.20))Web sürümündeki tek hücrelerde ayrı dosya oluşturmak her zaman uygun değildir; bu nedenle modül örneklerini bu hafta çoğunlukla statik olarak okuyacağız. Yerel Python ortamınızda iki dosyayla deneyin.
__name__ == "__main__" ne işe yarar?
Bir dosya doğrudan çalıştırıldığında __name__ değeri "__main__" olur. Modül olarak import edildiğinde modül adını alır.
def main():
print("Program başladı")
if __name__ == "__main__":
main()Bu desen, tanımlar ile doğrudan çalıştırılan örnek/ana akışı ayırmaya yardımcı olur. Bu dönem ayrıntılı paketleme mekanizmasına girmiyoruz; 13. haftada çok dosyalı OOP sisteminde yeniden kullanacağız.
Alıştırma — return ekle
Beklenen çıktı:
0
8
def clamp_zero(value):
if value < 0:
return 0
return valueAlıştırma — Yan etkiyi tahmin et
- Çıktıyı tahmin edin.
- Fonksiyonun çağıranın listesini değiştirmesini istemeseydik hangi yaklaşımı kullanabilirdik?
- Bu davranışın fonksiyon adından anlaşılması yeterli mi, yoksa dokümantasyon/sözleşme de gerekli mi?
Alıştırma — Büyük fonksiyonu ayır
Aşağıdaki görevi en az üç fonksiyon sorumluluğuna bölün; tam kod yazmanız gerekmiyor:
Bir CSV dosyasından ürünleri oku, fiyatı 1000 TL üzerindeki ürünleri bul, yüzde 10 indirim uygula ve sonucu ekrana yaz.
Örneğin read_products, discount_price, select_expensive gibi adlar düşünebilirsiniz. Ama her fonksiyonun tek ve açık bir işi olmasına dikkat edin.
Küçük üretim görevi — Not yardımcı modülü
Yerel ortamınızda iki dosya oluşturun:
grades.py içinde:
average(scores)is_successful(score, limit=50)
fonksiyonlarını tanımlayın.
app.py içinde bu fonksiyonları import edip birkaç örnek veriyle kullanın. Ardından grades.py dosyasını doğrudan çalıştırdığınızda küçük bir demo gösteren main() fonksiyonu ekleyin.
Kendinizi kontrol edin
print()ilereturnarasındaki fark nedir?- Yerel değişken neden fonksiyon dışından erişilemez?
- Liste parametresi üzerinde
append()yapmak çağıranı neden etkileyebilir? - “Parametre adı aynı nesneye bağlanır” modeli neyi açıklamaya yardımcı olur?
- Modül ne sağlar?
if __name__ == "__main__":kalıbının temel amacı nedir?
Bu haftadan akılda kalması gerekenler
- Fonksiyon, yalnızca kod tekrarını azaltan değil, sorumluluğu adlandıran bir yapıdır.
returnsonucu çağırana verir;printyalnızca çıktı üretir.- Fonksiyon çağrısında parametre adları verilen nesnelere bağlanır; mutable nesnelerde yerinde değişiklik ortak nesneyi etkileyebilir.
- Değiştirilebilir parametrelerde yan etkiyi bilinçli yönetin.
- Modüller programı fiziksel dosyalara ayırırken sorumluluk sınırlarını da görünür hâle getirir.
- Bu fikirler sınıf metotları ve çok dosyalı nesne modelleri için temel olacaktır.