Python'da kapsam (scope), bir değişkenin kodun hangi bölgesinden erişilebilir olduğunu belirleyen kuraldır. Fonksiyon içinde tanımlanan değişkenler local kapsamda yaşar ve sadece o fonksiyon içinde geçerlidir; fonksiyon dışında tanımlananlar ise global kapsamda yer alır ve programın her yerinden okunabilir. Global bir değişkeni fonksiyon içinden değiştirmek istediğinizde ise global anahtar kelimesini kullanmanız gerekir, aksi halde Python otomatik olarak yeni bir local değişken oluşturur.
Kapsam (Scope) Nedir?
Kapsam, bir değişkenin, fonksiyonun veya nesnenin kod içinde "görünür" ve kullanılabilir olduğu bölgeyi ifade eder. Python bir değişkene her eriştiğinde, o değişkeni önce en yakın kapsamda arar, bulamazsa daha dış kapsamlara doğru ilerler. Bu davranış, aynı isimde birden fazla değişkenin farklı kapsamlarda çakışmadan var olabilmesini sağlar.
Python'da temel olarak iki kapsam türünden bahsedilir: local scope (yerel kapsam) ve global scope (küresel kapsam). Local kapsam, bir fonksiyonun çalışması sırasında oluşur ve fonksiyon sona erdiğinde o kapsamdaki değişkenler de yok olur. Global kapsam ise modül seviyesinde tanımlanır ve program çalıştığı sürece bellekte kalır. Bu ayrımı anlamak, değişkenlerin nerede tanımlanması gerektiğine ve fonksiyonlar arasında veri paylaşımının nasıl yapılacağına dair doğru kararlar almanızı sağlar.
Local ve Global Değişken Farkı

Bir değişken fonksiyon içinde tanımlandığında local, fonksiyon dışında tanımlandığında global kabul edilir. Aşağıdaki örnek bu farkı gösterir:
isim = "Ahmet" # global değişken
def selamla():
mesaj = "Merhaba" # local değişken
print(mesaj, isim)
selamla()
print(isim) # çalışır, global değişken erişilebilir
print(mesaj) # NameError: mesaj tanımlı değil
Bu örnekte isim global kapsamda olduğu için hem fonksiyon içinden hem dışından okunabilir. Ancak mesaj değişkeni sadece selamla fonksiyonunun local kapsamında var olduğundan, fonksiyon dışında çağrıldığında NameError hatası alınır. Bir fonksiyon çalıştığında kendine ait bir local kapsam oluşturur ve bu kapsam fonksiyon bittiğinde silinir. Global değişkenler ise fonksiyonlar tarafından sadece okunabilir; herhangi bir fonksiyon içinde global bir değişkene doğrudan değer atamaya çalışmak, Python'un o ismi local bir değişken olarak yorumlamasına yol açar.
global Anahtar Kelimesinin Kullanımı
Bir fonksiyon içinden global bir değişkenin değerini değiştirmek istiyorsanız, Python'a bu değişkenin global kapsamda olduğunu açıkça belirtmeniz gerekir. Bunun için global anahtar kelimesi kullanılır:
sayac = 0
def arttir():
global sayac
sayac += 1
arttir()
arttir()
print(sayac) # 2
global ifadesi olmadan sayac += 1 satırı çalıştırıldığında Python, sayac değişkenini local kapsamda yeni bir değişken olarak oluşturmaya çalışır ve henüz atanmadığı için UnboundLocalError hatası verir. global anahtar kelimesi, fonksiyona "bu ismi local olarak değil, dıştaki global kapsamdaki değişken olarak kullan" talimatını verir. Bu yöntem pratik olsa da, fonksiyonların yan etkiler üretmesine (side effect) yol açtığı için genellikle değişkeni parametre olarak geçip yeni değeri return etmek daha temiz bir tasarım kabul edilir.
nonlocal ve İç İçe Fonksiyonlar
Python'da bir fonksiyonun içinde başka bir fonksiyon tanımlandığında, iç fonksiyon dış fonksiyonun kapsamına erişebilir. Bu ara kapsana "enclosing" (kapsayan) kapsam denir. İç fonksiyon dış fonksiyonun değişkenini okuyabilir ama değiştirmek isterse nonlocal anahtar kelimesini kullanması gerekir:
def disaridaki():
sayac = 0
def icerideki():
nonlocal sayac
sayac += 1
return sayac
print(icerideki()) # 1
print(icerideki()) # 2
print(sayac) # 2
disaridaki()
nonlocal sayac satırı olmasaydı, sayac += 1 işlemi icerideki fonksiyonu için yeni bir yerel değişken oluşturmaya çalışır ve UnboundLocalError hatası verirdi. nonlocal, Python'a "bu değişkeni burada değil, beni saran en yakın fonksiyonun kapsamında ara" der. global ile farkı burada: global doğrudan global kapsama gider, nonlocal ise araya giren fonksiyon kapsamlarına bakar.
LEGB Kuralı

Python bir değişkeni ararken belirli bir sırayı takip eder. Bu sıraya LEGB kuralı denir ve dört kapsamdan oluşur:
- Local (Yerel): İçinde bulunulan fonksiyonun kendi kapsamı.
- Enclosing (Kapsayan): İç içe fonksiyonlarda, dıştaki fonksiyonun kapsamı.
- Global: Modülün en üst seviyesindeki kapsam.
- Built-in (Yerleşik): Python'ın kendi içinde tanımlı olan
len,print,rangegibi isimler.
Python bir ismi çözümlerken bu sırayla arama yapar; önce Local'e bakar, bulamazsa Enclosing'e, sonra Global'e, en son da Built-in kapsamına geçer. İlk bulduğu eşleşmeyi kullanır ve aramayı durdurur.
x = "global x"
def disaridaki():
x = "enclosing x"
def icerideki():
x = "local x"
print(x) # local x
icerideki()
disaridaki()
Bu örnekte icerideki fonksiyonu kendi x değişkenine sahip olduğu için arama Local seviyesinde durur. Eğer icerideki içinde x tanımlı olmasaydı, sırasıyla Enclosing ve Global kapsamlara bakılırdı.
Python'da bir ad kullanıldığında ad çözümlemesi, ilgili kod bloğuna en yakın kapsamdan başlayarak yapılır: yerel kapsam (Local), varsa iç içe fonksiyonların kapsayan kapsamları (Enclosing), modülün genel kapsamı (Global) ve yerleşik adlar kapsamı (Built-in).
Sık Yapılan Hatalar
Kapsam konusunda en sık karşılaşılan hata UnboundLocalError'dır. Bu hata, bir değişkene fonksiyon içinde atama yapılırken Python'ın o değişkeni otomatik olarak yerel kabul etmesinden kaynaklanır:
sayi = 10
def guncelle():
print(sayi) # UnboundLocalError
sayi = sayi + 1
guncelle()
Burada sayi = sayi + 1 satırı, Python'a sayi'nin bu fonksiyon içinde yerel bir değişken olduğunu söyler. Ancak print(sayi) satırı bu atamadan önce çalıştığı için, henüz tanımlanmamış bir yerel değişkene erişilmeye çalışılır ve hata oluşur. Çözüm, değişkeni global olarak kullanmak istiyorsak global sayi eklemektir.
Başka bir yaygın hata, döngü içinde tanımlanan fonksiyonların döngü değişkenini "geç bağlama" (late binding) yüzünden beklenmedik şekilde kullanmasıdır:
fonksiyonlar = [lambda: i for i in range(3)]
print([f() for f in fonksiyonlar]) # [2, 2, 2] beklenmez ama olur
Bu hatanın çözümü, değişkeni varsayılan parametre olarak yakalamaktır: lambda i=i: i. Kapsam hatalarının çoğu, bir değişkenin hangi kapsamda "yaşadığını" net anlamakla önlenebilir.
İlgili Kaynaklar
Kapsam kavramını pekiştirmenin en iyi yolu bol örnekle pratik yapmaktır. Fonksiyonlar, değişken tanımları ve global/local ayrımını uygulamalı olarak görmek için Python programı sayfasındaki alıştırmaları inceleyebilirsin. Öğrendiklerini ölçmek istersen de bilgi testi ile kendini test edebilir, LEGB kuralı ve global anahtar kelimesiyle ilgili sık karşılaşılan senaryoları tekrar gözden geçirebilirsin.
Sık Sorulan Sorular
Global değişkeni fonksiyon içinde değiştirmek neden hataya sebep olur?
Python, bir fonksiyon içinde değişkene değer atadığını gördüğünde onu otomatik olarak local kabul eder. Eğer o değişken henüz local olarak tanımlanmadan önce okunmaya çalışılırsa "local variable referenced before assignment" hatası alırsın. Çözüm için değişkeni global anahtar kelimesiyle tanımlaman gerekir.
global ve nonlocal arasındaki temel fark nedir?
global, bir değişkenin en dıştaki modül seviyesindeki haline erişmeni sağlar. nonlocal ise iç içe fonksiyonlarda, bir üst fonksiyonun local değişkenine erişmek için kullanılır. Yani nonlocal modül seviyesine değil, bir ara kapsama işaret eder.
Bir değişken hem local hem global olarak aynı isimle var olabilir mi?
Evet, Python bunu sorunsuz kabul eder. Fonksiyon içindeki local değişken, aynı isimdeki global değişkeni geçici olarak gizler. Fonksiyon çalışırken sadece local olan kullanılır, fonksiyon bitince global değişken etkilenmemiş şekilde kalır.
LEGB kuralını hatırlamak için pratik bir yol var mı?
LEGB sırasını, Python'un bir değişkeni ararken izlediği yol olarak düşünebilirsin: önce en yakın fonksiyon (Local), sonra onu saran fonksiyon (Enclosing), sonra modül seviyesi (Global), son olarak da Python'un kendi yerleşik isimleri (Built-in). Bu sırayı bir kod örneğinde adım adım takip etmek, kuralı ezberlemekten daha kalıcı olur.
Kapsam kuralları ilk bakışta karmaşık görünse de düzenli pratikle oturan bir konu. Küçük örnekler üzerinden değişkenlerin nerede tanımlandığını ve nereden erişildiğini takip ettikçe, global ve local ayrımı zamanla doğal bir refleks haline gelir.