Kaynak eski ve Python2 için yazılmış, şuanki CPython için bilgi yanlışları var. Hatta Python2 için de yanlış bilgi var.
Python3’te __builtin__
yerine __builtins__
var.
>>> __builtin__
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
__builtin__
NameError: name '__builtin__' is not defined
>>> __builtins__
<module 'builtins' (built-in)>
__name__
değişkeni modül globallerinin bir parçası ve her modülün kendi __name__
değişkeni var.
>>> __name__ is __builtins__.__name__
False
>>> __name__ is globals()["__name__"]
True
>>> __name__
'__main__'
>>> __builtins__.__name__
'builtins'
Yerel alan, yerel değişkenlerin bulunduğu alan oluyor. Yerel değişkenler de yerel alanda oluşturulan sıradan değişkenler.
Fonksiyonlar kendi alanlarına (scope) sahipler, bir değişken hangi alanda oluşturulursa o alana ait olur.
Herhangi bir fonksiyonun içinde tanımlanan başka herhangi bir fonksiyona enclosed fonksiyon deniyor:
def herhangi_bir_fonksiyon():
def bir_enclosed_fonksiyon():
...
Python’un isim çözümlemesi (name resolution) basit, kendi alanına sahip olan üç şey var: modüller, sınıflar ve fonksiyonlar.
Modül alanlarına global alan da deniliyor. globals
fonksiyonu içinde çağırıldığı modülün alanını dict
olarak döndürüyor, çünkü alanlar zaten birer dict
:
>>> a = 1
>>> b = "c"
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:\\Users\\Dinçel\\Desktop\\client.py', 'a': 1, 'b': 'c'}
Sınıfların ve fonksiyonların alanlarına yerel alan deniyor. Sınıfların isim çözümlemesindeki yerleri küçük. Ama nitelik çözümlemesinde (attribute resolution) önemliler.
Bir isme erişilmeye çalışıldığında:
- Eğer yerel bir alanda isek önce bulunduğumuz yerel alana bakılır. Orada bulunamaz ise:
- Eğer içinde bulunduğumuz yerel alan -alanın ait olduğu sınıf veya fonksiyonun kullanıldığı değil, tanımlandığı yer olarak- herhangi bir veya birden fazla fonksiyonun içinde bulunuyor ise en iç fonksiyonun alanından başlayarak en sondaki fonksiyonun alanına kadar isim için kontrol yapılır (bu kuralın yan etkilerinden biri de late binding oluyor), bulunamaz ise son maddede belirttiğim şekilde global alana bakılır.
- Eğer içinde bulunduğumuz yerel alan herhangi bir fonksiyonun içinde değilse global alana bakılır. Global alana bakarken aşağıdaki kural geçerli.
- Eğer yerel bir alanda değil isek, yani global alanda isek direkt global alana bakılır. Orada bulunamaz ise
__builtins__
'e bakılır. Orada da bulunamaz ise NameError
yükseltilir.