Değişken kapsamlarının ne olduğunu öğrenin ve 'LEGB' kuralına aşina olun. Ayrıca global ve nonlocal anahtar sözcüklerini iş başında göreceğiniz senaryolarla karşılaşacaksınız.
Yalnızca birkaç satır yazdıktan sonra “name is not defined” veya “local variable referenced before assignment” mesajlarını görmek sinir bozucudur. Kod doğru görünüyor ama Python aynı fikirde değildir. Bunun temel nedeni neredeyse her zaman kapsamdırr: bir ismin nerede görünür olduğu ve o anda hangi nesneye karşılık geldiği.
Python’un isim aramasını—genellikle LEGB kuralı olarak özetlenir—anladığınızda, bu hatalar öngörülebilir ve kolayca düzeltilebilir hale gelir. Bu eğitimde, Python’da değişkenleri ve kapsamları adım adım ele alacağım.
Değişken Nedir?
Değişken, bir nesneye bağlı (bağlı) bir isimdir. Python’da atama operatörü = ile bir bağ oluşturursunuz. İsimler türlü değildir; herhangi bir nesneyi (string, int, list, function vb.) gösterebilirler.
Sözdizimi hatalarından ve ince hatalardan kaçınmak için değişken adı verirken şu kurallara ve geleneklere uyun.
Yalnızca harfler, rakamlar ve alt çizgi kullanın; isimler bir rakamla başlayamaz.
True, for veya class gibi anahtar sözcükleri isim olarak kullanmayın.
list, dict, sum veya max gibi yerleşikleri gölgelemekten kaçının.
Okunabilirlik için snake_case tercih edin (PEP 8).
Aşağıdaki örnekler nelerin yapılmaması gerektiğini ve Python’un hangi hataları verdiğini gösterir:
first string value ="First string"# spaces not allowed# SyntaxError: invalid syntax
1st_value =10# cannot start with a digit# SyntaxError: invalid decimal literalTrue="yes"# cannot assign to a keyword# SyntaxError: cannot assign to TrueAltyapı:
Python’da Kapsam Nasıl Çalışır (LEGB)
Kapsam, bir ismin görünür olduğu kod bölgesidir. Bir ismi kullandığınızda Python şu sırayla arar (LEGB):
Local: mevcut fonksiyonun kapsamı.
Enclosing: iç içe fonksiyonlar için dıştaki fonksiyon kapsamları.
Global: modülün en üst düzeyi (modül ad alanı).
Built-in: Python’un builtins içinde tanımladığı isimler (örneğin len, print).
İsimler ad alanlarında yaşar (isimleri nesnelere eşleyen sözlükler gibi düşünün). Kapsam, kodun belirli bir noktasında bir ismi çözmek için Python’un hangi ad alanlarına baktığıyla ilgilidir.
Yerel kapsam
Bir fonksiyon içinde atanan isimler, aksi belirtilmedikçe o fonksiyona yereldir. Fonksiyonun dışında görünür değillerdir.
Python kapsamı derleme zamanında belirler. Bir fonksiyon gövdesinin herhangi bir yerinde bir isme atama yapılıyorsa, o isim fonksiyon içindeki tüm kullanımlarda yerel kabul edilir—ve atamadan önce okumaya çalıştığınızda yaygın bir UnboundLocalError oluşur:
discount_rate =0.10# module-level (global)defprice_with_discount(amount_cents):print("configured discount:", discount_rate)# looks local because of the assignment below
discount_rate =0.20# assignment makes 'discount_rate' local in this functionreturnint(amount_cents *(1- discount_rate))# UnboundLocalError: cannot access local variable 'discount_rate' where it is not associated with a valueAltyapı:
Fonksiyonda modül düzeyindeki ismi kullanmak için ya ona atama yapmaktan kaçının ya da onu global olarak işaretleyin (aşağıda ele alınmıştır).
Kapsayan kapsam (kapanımlar)
İç içe fonksiyonlar, kendilerini hemen saran fonksiyondaki isimleri görebilir. Böyle bir ismi yeniden bağlamak (sadece okumak değil) için nonlocal bildirin.
defmake_step_counter():
count =0# enclosing scope for 'increment'defincrement():nonlocal count # rebind the 'count' in the nearest enclosing function
count +=1return count
return increment
step = make_step_counter()print(step())# 1print(step())# 2Altyapı:
nonlocal olmadan, increment() içinde count’a atama yapmak yeni bir yerel isim oluşturur ve dıştaki count değişmeden kalır.
Global kapsam
Bir modülün en üst düzeyinde atanan isimler, modülün global ad alanında yaşar. Her fonksiyon bunları okuyabilir. Bir fonksiyon içinden modül düzeyindeki bir isme atama yapmak için onu global olarak bildirin.
greeting ="Hello"defgreet_city(city_name):print(greeting, city_name)# reads globaldefset_greeting(new_greeting):global greeting
greeting = new_greeting # rebinds global
greet_city("Nairobi")# Hello Nairobi
set_greeting("Hi")
greet_city("Nairobi")# Hi NairobiAltyapı:
global’ı ölçülü kullanın. Kodun test edilebilir ve öngörülebilir kalması için değerleri parametre olarak geçirmeyi ve sonuçları döndürmeyi tercih edin.
Yerleşik kapsam (ve anahtar sözcükler hakkında bir not)
Yerleşik kapsam, len, print ve Exception gibi isimleri içerir. Bunları gölgelemekten kaçının; aksi halde o kapsamda yerleşik işlevi kaybedersiniz.
list=[1,2,3]# shadows the built-in 'list' constructorlist("abc")# TypeError: 'list' object is not callabledellist# fix by deleting the shadowing nameAltyapı:
Anahtar sözcükler (if, for, def gibi) Python’un sözdiziminin parçasıdır, yerleşik ad alanının değil, ve asla tanımlayıcı olarak kullanılamazlar.
Bloklar, Döngüler ve Anlamalar
Python’un blok ifadeleri ve anlamaları, diğer dillerden gelen geliştiricileri sıkça şaşırtan belirli kapsam davranışlarına sahiptir.
if/for/while/with için blok kapsamı yoktur
Bu blokların içindeki atamalar, kapsayan kapsamı (fonksiyon veya modül) etkiler. Döngü değişkenleri de döngü bittikten sonra tanımlı kalır.
ifTrue:
status ="ready"print(status)# "ready"for i inrange(3):passprint(i)# 2 (the last value from the loop)Altyapı:
Anlamalar yineleme değişkenlerini izole eder
Liste, sözlük ve küme anlamalarının döngü değişkenleri için kendi yerel kapsamları vardır. Yineleme değişkeni çevreleyen kapsama sızmaz.
numbers =[1,2,3][x for x in numbers]print("x"inglobals()or"x"inlocals())# FalseAltyapı:
Python 3.12 (PEP 709), hız için anlamaları satır içine alırken bu izolasyonu korudu; hâlâ net, sızmayan döngü değişkenleri ve daha hızlı yürütme elde edersiniz.
global Anahtar Sözcüğünü Kullanma
Bir ismi global olarak bir fonksiyon içinde, modül düzeyindeki bir değişkeni yeniden bağlamanız gerektiğinde bildirin. Hangi değişkeni değiştirdiğinizin açık olması için bildirimi fonksiyonun başına yakın bir yere koyun.
En yakın kapsayan fonksiyon kapsamındaki bir ismi yeniden bağlamak için nonlocal kullanın. Bu, durum tutan kapanımlarda yaygındır.
defmake_accumulator(start=0):
total = start
defadd(amount):nonlocal total
total += amount
return total
return add
acc = make_accumulator()print(acc(5))# 5print(acc(10))# 15Altyapı:
nonlocal’ın, bir kapsayan fonksiyonda tanımlı olmayan bir isim için kullanılması bir SyntaxError’dır. İsim global ise bunun yerine global kullanın.
locals() ve globals() 2025’te
Bu işlevler inceleme ve hata ayıklama için kullanışlıdır, değişken güncellemek için değil. Python 3.13’ten (PEP 667) itibaren, fonksiyon içindeki her locals() çağrısı bağımsız bir anlık görüntü döndürür. Bu anlık görüntüyü düzenlemek gerçek yerelleri değiştirmez. Bu davranışı Python 3.13’te aşağıdaki parçacığı çalıştırarak doğruladım:
defprobe():
project ="alpha"
snap1 =locals()
snap1["project"]="beta"# edits the snapshot only
observed = project # still "alpha"
snap2 =locals()# new snapshotreturn snap1["project"], observed, snap2["project"]print(probe())# ('beta', 'alpha', 'alpha')Altyapı:
globals()’ı modül ad alanı için benzer şekilde kullanın. Uygulama kodu yazarken dinamik aramalar yerine açık parametreleri ve dönüş değerlerini tercih edin.
Yaygın Tuzaklar ve Nasıl Düzeltilir
Bu hatalar, pratikte gördüğüm kapsamla ilgili hataların çoğunu oluşturur.
UnboundLocalError—fonksiyon içinde atamadan kaynaklanır: Python, bir isme fonksiyonda herhangi bir yerde atama varsa o ismi yerel sayar. Okumayı atamadan sonraya alın, ismi değiştirin ya da uygun şekilde global/nonlocal ekleyin.
Blok kapsamı beklemek: if/for/while/with içinde atanan isimler, kapsayan kapsamda kalıcıdır. Kapsamı sınırlamak için daha dar yardımcı fonksiyonlar kullanın.
Yerleşikleri gölgeleme: list, dict, sum, id veya min gibi isimlerden kaçının. customer_list veya min_allowed gibi açıklayıcı isimler seçin.
Kapanımlarda nonlocal’ı unutmak: Dıştaki bir fonksiyon değişkenini güncellemeyi amaçlıyorsanız, onu nonlocal olarak bildirin. Aksi halde yeni bir yerel oluşturur ve dıştaki değer değişmez.
Anahtar sözcükleri yerleşiklerle karıştırmak: Anahtar sözcükler (sözdizimi) asla isim olarak kullanılamaz. Yerleşikler gölgelenebilir ama gölgelenmemelidir.
Kapsamı Basit Tutan En İyi Uygulamalar
Bu alışkanlıklar kodu okumayı, test etmeyi ve hata ayıklamayı kolaylaştırır.
Küçük, odaklı fonksiyonları tercih edin. Değişkenleri işe yarayan en dar kapsamda tanımlayın.
Verileri parametrelerle içeri ve dönüş değerleriyle dışarı taşıyın. Modül düzeyindeki durumu en aza indirin.
Kapanımları bilinçli kullanın. Bir iç içe fonksiyonun hangi dış isimleri yakaladığını belgelendirin ve gerçekten yeniden bağlamanız gerektiğinde nonlocal kullanın.
Çatışmayan, açıklayıcı isimler seçin. Önde gelen alt çizgi (ör. _cache) dahili kullanım sinyali verir.
locals()/globals()’ı yapılandırma mekanizması değil, salt okunur tanılama olarak ele alın.
Sonuç
Python, isimleri Yerel → Kapsayan → Global → Yerleşik kapsamlarında arayarak çözer. Bu sırayı—ve ne zaman global veya nonlocal kullanmanız gerektiğini—anlamak, NameError ve UnboundLocalError gibi yaygın hataları ortadan kaldırır. Değişkenleri mümkün olan en küçük kapsamda tutun, yerleşikleri gölgelemekten kaçının ve kapanımları bilinçli kullanın. Bu zihinsel modelle fonksiyonlarınız öngörülebilir davranır ve kapsam sürpriz kaynağı olmaktan çıkar.
Çeşitli sektörlerde çalıştım ve birden çok rol üstlendim: yazılım geliştirici, makine öğrenimi araştırmacısı, veri bilimci, ürün yöneticisi. Ancak özünde, öğrenmeyi ve bilgiyi paylaşmayı seven bir programcıyım!
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Yalnızca birkaç satır yazdıktan sonra “name is not defined” veya “local variable referenced before assignment” mesajlarını görmek sinir bozucudur. Kod doğru görünüyor ama Python aynı fikirde değildir. Bunun temel nedeni neredeyse her zaman kapsamdırr: bir ismin nerede görünür olduğu ve o anda hangi nesneye karşılık geldiği.
Python’un isim aramasını—genellikle LEGB kuralı olarak özetlenir—anladığınızda, bu hatalar öngörülebilir ve kolayca düzeltilebilir hale gelir. Bu eğitimde, Python’da değişkenleri ve kapsamları adım adım ele alacağım.
Değişken Nedir?
Değişken, bir nesneye bağlı (bağlı) bir isimdir. Python’da atama operatörü
=ile bir bağ oluşturursunuz. İsimler türlü değildir; herhangi bir nesneyi (string, int, list, function vb.) gösterebilirler.Sözdizimi hatalarından ve ince hatalardan kaçınmak için değişken adı verirken şu kurallara ve geleneklere uyun.
True,forveyaclassgibi anahtar sözcükleri isim olarak kullanmayın.list,dict,sumveyamaxgibi yerleşikleri gölgelemekten kaçının.snake_casetercih edin (PEP 8).Aşağıdaki örnekler nelerin yapılmaması gerektiğini ve Python’un hangi hataları verdiğini gösterir:
Python’da Kapsam Nasıl Çalışır (
LEGB)Kapsam, bir ismin görünür olduğu kod bölgesidir. Bir ismi kullandığınızda Python şu sırayla arar (LEGB):
builtinsiçinde tanımladığı isimler (örneğinlen,print).İsimler ad alanlarında yaşar (isimleri nesnelere eşleyen sözlükler gibi düşünün). Kapsam, kodun belirli bir noktasında bir ismi çözmek için Python’un hangi ad alanlarına baktığıyla ilgilidir.
Yerel kapsam
Bir fonksiyon içinde atanan isimler, aksi belirtilmedikçe o fonksiyona yereldir. Fonksiyonun dışında görünür değillerdir.
Python kapsamı derleme zamanında belirler. Bir fonksiyon gövdesinin herhangi bir yerinde bir isme atama yapılıyorsa, o isim fonksiyon içindeki tüm kullanımlarda yerel kabul edilir—ve atamadan önce okumaya çalıştığınızda yaygın bir
UnboundLocalErroroluşur:Fonksiyonda modül düzeyindeki ismi kullanmak için ya ona atama yapmaktan kaçının ya da onu
globalolarak işaretleyin (aşağıda ele alınmıştır).Kapsayan kapsam (kapanımlar)
İç içe fonksiyonlar, kendilerini hemen saran fonksiyondaki isimleri görebilir. Böyle bir ismi yeniden bağlamak (sadece okumak değil) için
nonlocalbildirin.nonlocalolmadan,increment()içindecount’a atama yapmak yeni bir yerel isim oluşturur ve dıştakicountdeğişmeden kalır.Global kapsam
Bir modülün en üst düzeyinde atanan isimler, modülün global ad alanında yaşar. Her fonksiyon bunları okuyabilir. Bir fonksiyon içinden modül düzeyindeki bir isme atama yapmak için onu
globalolarak bildirin.global’ı ölçülü kullanın. Kodun test edilebilir ve öngörülebilir kalması için değerleri parametre olarak geçirmeyi ve sonuçları döndürmeyi tercih edin.Yerleşik kapsam (ve anahtar sözcükler hakkında bir not)
Yerleşik kapsam,
len,printveExceptiongibi isimleri içerir. Bunları gölgelemekten kaçının; aksi halde o kapsamda yerleşik işlevi kaybedersiniz.Anahtar sözcükler (
if,for,defgibi) Python’un sözdiziminin parçasıdır, yerleşik ad alanının değil, ve asla tanımlayıcı olarak kullanılamazlar.Bloklar, Döngüler ve Anlamalar
Python’un blok ifadeleri ve anlamaları, diğer dillerden gelen geliştiricileri sıkça şaşırtan belirli kapsam davranışlarına sahiptir.
if/for/while/withiçin blok kapsamı yokturBu blokların içindeki atamalar, kapsayan kapsamı (fonksiyon veya modül) etkiler. Döngü değişkenleri de döngü bittikten sonra tanımlı kalır.
Anlamalar yineleme değişkenlerini izole eder
Liste, sözlük ve küme anlamalarının döngü değişkenleri için kendi yerel kapsamları vardır. Yineleme değişkeni çevreleyen kapsama sızmaz.
Python 3.12 (PEP 709), hız için anlamaları satır içine alırken bu izolasyonu korudu; hâlâ net, sızmayan döngü değişkenleri ve daha hızlı yürütme elde edersiniz.
globalAnahtar Sözcüğünü KullanmaBir ismi
globalolarak bir fonksiyon içinde, modül düzeyindeki bir değişkeni yeniden bağlamanız gerektiğinde bildirin. Hangi değişkeni değiştirdiğinizin açık olması için bildirimi fonksiyonun başına yakın bir yere koyun.nonlocalAnahtar Sözcüğünü KullanmaEn yakın kapsayan fonksiyon kapsamındaki bir ismi yeniden bağlamak için
nonlocalkullanın. Bu, durum tutan kapanımlarda yaygındır.nonlocal’ın, bir kapsayan fonksiyonda tanımlı olmayan bir isim için kullanılması birSyntaxError’dır. İsim global ise bunun yerineglobalkullanın.locals()veglobals()2025’teBu işlevler inceleme ve hata ayıklama için kullanışlıdır, değişken güncellemek için değil. Python 3.13’ten (PEP 667) itibaren, fonksiyon içindeki her locals() çağrısı bağımsız bir anlık görüntü döndürür. Bu anlık görüntüyü düzenlemek gerçek yerelleri değiştirmez. Bu davranışı Python 3.13’te aşağıdaki parçacığı çalıştırarak doğruladım:
globals()’ı modül ad alanı için benzer şekilde kullanın. Uygulama kodu yazarken dinamik aramalar yerine açık parametreleri ve dönüş değerlerini tercih edin.Yaygın Tuzaklar ve Nasıl Düzeltilir
Bu hatalar, pratikte gördüğüm kapsamla ilgili hataların çoğunu oluşturur.
UnboundLocalError—fonksiyon içinde atamadan kaynaklanır: Python, bir isme fonksiyonda herhangi bir yerde atama varsa o ismi yerel sayar. Okumayı atamadan sonraya alın, ismi değiştirin ya da uygun şekilde global/nonlocal ekleyin.customer_listveyamin_allowedgibi açıklayıcı isimler seçin.nonlocal’ı unutmak: Dıştaki bir fonksiyon değişkenini güncellemeyi amaçlıyorsanız, onu nonlocal olarak bildirin. Aksi halde yeni bir yerel oluşturur ve dıştaki değer değişmez.Kapsamı Basit Tutan En İyi Uygulamalar
Bu alışkanlıklar kodu okumayı, test etmeyi ve hata ayıklamayı kolaylaştırır.
_cache) dahili kullanım sinyali verir.Sonuç
Python, isimleri Yerel → Kapsayan → Global → Yerleşik kapsamlarında arayarak çözer. Bu sırayı—ve ne zaman global veya nonlocal kullanmanız gerektiğini—anlamak,
NameErrorveUnboundLocalErrorgibi yaygın hataları ortadan kaldırır. Değişkenleri mümkün olan en küçük kapsamda tutun, yerleşikleri gölgelemekten kaçının ve kapanımları bilinçli kullanın. Bu zihinsel modelle fonksiyonlarınız öngörülebilir davranır ve kapsam sürpriz kaynağı olmaktan çıkar.