11. derste bulunan A, B, C bölümlerini istediğiniz sırayla tamamlayabilirsiniz.
Bu derste değişken kapsamı olarak adlandırılan bir kavramı ele alacağız. Ana fikir, iki farklı değişkene farklı kapsamlarda yer aldıkları her durumda aynı ismin verilebilmesidir. Bu, özellikle de geniş çaplı programları yazmayı ve düzenlemeyi kolaylaştırır. Ayrıca bu kavrama, daha ileride göreceğimiz yineleme konusunda ihtiyacımız olacak.
Değişken Kapsamına Bir Örnek
Bu örnekte kullanacağımız programın bir bölümü şöyle:
def kare(x): değer = x * x return değerBu,
x
, sayısının karesini hesaplayan bir fonksiyon, yani kare(5)
return sonucu 25
olacak. Şimdi diyelim, kare
fonksiyonunu, programın değer
adlı değişkeni başka bir amaçla kullandığı bir bölümünde tekrar çağırdık:
# Programın ana gövdesi burada başlıyor değer = 17 beşinKaresi = kare(5) print(beşinKaresi, değer)Soru şu, program çıktı olarak ne yazdıracak? İki ihtimal var, eğer Python'un nasıl çalıştığını bilmiyorsak:
- Birinci ihtimal, Python iki
değer
değişkeninin bir şekilde ayrı tutulması gerektiğini anlayacak. Böylecekare
25 sonucunu verirken,değer
değişkeni ana gövdede 17 olduğu gibi kalacak, ve program25
17
sonucunu verecek. - Diğer ihtimal de,
kare
fonksiyonu işleme konduğundadeğer
değişkeninin mevcut karşılığı yerine 25 getirilecek ve sonuç olarak da program25
25
çıktısını verecek.
Bakalım gerçekte ne olacak!
Python 1. ihtimale göre davranacaktır. Çünkü, bir fonksiyon çağrıldığı zaman, fonksiyonun dışında tanımlanmış hiçbir değişken etkilenmez. Değişkenlere atanmış değerler sadece "yerel" işlemleri, yani fonksiyonun "içindeki" işlemleri etkiler. Python ve diğer çoğu programlama dillerinde bunu yapabilmemizin sebebi; bu şekilde içinde pek çok fonksiyon bulunan çok uzun programları daha basit olarak yazabiliriz. Yeni bir fonksiyon tanımladığımızda, fonksiyonun içinde herhangi bir değişken adını (result,
temp
vei
gibi son derece genel kelimeler de dâhil) kullanmaya her zaman izin verilir, isterse bu değişkenler programın başka yerlerinde, hatta başka fonksiyonların içinde defalarca kullanılmış olsun.
Bunu detaylı olarak görmek için, görüntüleyicide 8 adımın 6.sına bakabilirsiniz. Burada değer
adıyla tanımlanmış iki farklı değişken göreceksiniz; bir tanesi kare
fonksiyonunun içinde diğeri de dışarıda ("global" kısımda).
x = "dış"
def xDeğiş(değer):
x = değer
xDeğiş("iç")
print(x)
x = değer
ifadesi sadece x
değişkeninin yerel versiyonudur ve sadece fonksiyonun içinde geçerlidir. x
değişkeninin global versiyonu değişmez. (Yani, xDeğiş
fonksiyonunun hiçbir etkisi olmayacaktır.)Kapsama (scope) benzeyen başka bir kavram da isim alanıdır (namespace); isim alanı paketin kapsamı gibidir. Diyelim bir yerde x
değişkenini kullanan bir paket ithal (import
) ederseniz (math
matematik gibi), buradaki x
hiçbir şekilde programın diğer yerlerindeki x
değişkeni ile karışmaz, çünkü farklı isim alanlarında yer almaktadırlar.
Kapsama Kuralları: Dışarı Yolla
Bazı durumlarda lokal ve global kapsamdaki değişkenleri birlikte kullanmak isteyebiliriz. Yaygın bir örnek olarak, programın ilk kısmında oluşturduğunuz genel bazı değişkenlerin fonksiyonunuzun içinde de okunmasını istersiniz.
Burada, yerel kapsamda neliPizza
diye bir değişkenimiz yok, ama bu bir hataya yol açmıyor. Python, değişkenleri ele alırken, eğer bir değişken, kendisine ihtiyaç duyulan lokal kapsamda yer almıyorsa, onu global kapsamda arar. Bizim örneğimizde neliPizza
değişkeni global kapsamda var. (Bir fonksiyon gövdesinin başka bir fonksiyon gövdesini çağırdığı daha genel bir durumda, bu kez üç kapsam elde ederiz; Python daima önce "en yerel" olanı denetler ve değişkeni bulana kadar adım adım kapsamları tarar.)
Yukarıdaki örneklerin ikisi, pizzaSiparişi ve xDeğiş , fonksiyonları sentaks olarak aynıdır. Pekiyi, Python xDeğiş fonksiyonunda yeni bir lokal değişken olarak x değişkenini yaratırken, yeni bir neliPizza değişkenini pizzaSiparişi fonksiyonu için neden oluşturmadı? Python'un bu konudaki kuralı şöyledir: Eğer değişkeni sadece okuyorsanız, yeni lokal değişken yaratılmaz; ama eğer değişkeni en az bir kez de olsa yazdıysanız, değişken tüm fonksiyon gövdesi boyunca lokal kapsamda değerlendirilir. (Bu durum UnboundLocalError hatasının en yaygın sebebidir: Python resmi sayfalarında yer alan şu iki soruya göz atın [1, 2].) |
Fonksiyon argümanları her zaman lokal değişken olarak kabul edilir. Buradaki kırık program parçasından görebilirsiniz (g
değişkenini 0
olarak resetlemeye çalışıyor ama işe yaramıyor).
global
Değişiklikler
Diğer pek çok şey gibi, yukarıda anlatılan normal akış tüm durumların %99'u için geçerlidir, ama kalan %1'lik durumlar için bir fonksiyon içine yerleştirdiğiniz global bir değişkenin yerine başka bir isim seçmeniz gerekebilir. Python'da bunu global
bir ifade kullanarak yapabilirsiniz.
Yukarıda geçen xDeğiş
örneğini burada farklı bir şekilde yazdık; değişkeni fonksiyon içinde global olarak ilan etmek, değişkenin global değerini fonksiyonun içinden değiştirmemize izin verir.
Bir fonksiyonun içerisinde global kapsamda tanımlanmış bir değişkene bir değer atadığımızda; global değişken güncellenmiş olmaz, sadece lokal kapsamda aynı isimle yeni bir değişken yaratılmış olur. Eğer global kapsamlı değişkenin değerini fonkisyon içinde güncellemek isterseniz, fonksiyonun içerisinde "global <değişken adı>" ifadesini kullanmanız gerekir. Böylece Python, değişkenin değerinde yaptığımız değişikliğin global kapsamdaki değişken için de geçerli olacağını anlar. Dersimizi bu bilgi ile bitiriyoruz!