Python'da değişken, bir değeri içinde saklayan bir kutu değil, bir nesneye bağlanmış bir isimdir. x = 5 yazdığınızda Python 5 değerini taşıyan bir tamsayı nesnesine x adını bağlar; değişkenin kendisinin bir tipi yoktur, tip her zaman nesneye aittir. Temel veri tipleri int (tamsayı), float (ondalıklı sayı), str (metin), bool (True/False) ve "değer yok" anlamındaki None'dır; bir değerin tipini type() ile, belirli bir tipten olup olmadığını isinstance() ile öğrenirsiniz.
Bu basit tanım, yeni başlayanların en çok takıldığı davranışların anahtarıdır: iki değişkenin aynı listeyi göstermesi, bir fonksiyonun aldığı listeyi değiştirebilmesi ama aldığı sayıyı değiştirememesi, == ile is arasındaki fark. Bu yazı Language Reference'ın veri modeli bölümüne dayanarak nesne kimliğini, tipini ve değerini, değiştirilebilir ve değiştirilemez tipleri, isimlendirme kurallarını ve sık yapılan hataları örneklerle anlatıyor. Serinin tamamı Python öğrenme rehberi sayfasında.
Temel veri tipleri

Python'da her değer bir nesnedir ve her nesnenin bir tipi vardır. Aşağıdaki döngü, en sık kullanacağınız beş temel tipten birer değeri tipinin adıyla birlikte yazdırıyor:
sayi = 42
oran = 3.14
ad = "Python"
aktif = True
bos = None
for deger in (sayi, oran, ad, aktif, bos):
print(type(deger).__name__, deger)
# çıktı: int 42
# çıktı: float 3.14
# çıktı: str Python
# çıktı: bool True
# çıktı: NoneType None| Tip | Örnek | Değiştirilebilir mi | Ayrıntı |
|---|---|---|---|
| int | 42, -7, 10**100 | Hayır | Sınırsız büyüklükte tamsayı |
| float | 3.14, 1e-3 | Hayır | İkili kayan nokta, genellikle C double |
| str | "merhaba" | Hayır | Unicode metin dizisi |
| bool | True, False | Hayır | int tipinin alt sınıfı |
| NoneType | None | Hayır | Tek bir nesnesi vardır |
| list | [1, 2] | Evet | Sıralı, değiştirilebilir dizi |
| tuple | (1, 2) | Hayır | Sıralı, değiştirilemez dizi |
| dict | {"a": 1} | Evet | Anahtar-değer eşlemesi |
| set | {1, 2} | Evet | Sırasız, benzersiz öğeler |
Sayılar sayılar yazısında, metinler string metotları yazısında, kap tipleri ise liste, tuple, sözlük ve küme yazılarında ayrıntılı işleniyor. Bu yazı tiplerin ortak davranışına odaklanıyor.
Kimlik, tip ve değer
Veri modeline göre her nesnenin üç özelliği vardır: kimlik, tip ve değer. Kimlik nesne oluşturulduktan sonra hiç değişmez; onu nesnenin bellekteki adresi gibi düşünebilirsiniz. id() fonksiyonu kimliği temsil eden bir tamsayı döndürür ve is operatörü iki ismin aynı nesneyi gösterip göstermediğini bu kimlik üzerinden karşılaştırır. CPython'da id(x) gerçekten bellek adresidir. Belgelere göre kimlik nesnenin ömrü boyunca benzersizdir; ama ömürleri çakışmayan iki nesne aynı id() değerini alabilir.
Tip, nesnenin hangi işlemleri desteklediğini ve alabileceği değerleri belirler; o da kimlik gibi değişmez. Değer ise bazı nesnelerde değişebilir, bazılarında değişemez. Değeri değişebilen nesnelere mutable (değiştirilebilir), değişemeyenlere immutable (değiştirilemez) denir. Sayılar, metinler ve tuple'lar değiştirilemez; listeler, sözlükler ve kümeler değiştirilebilir.
Atama bir isim bağlamaktır
Atama ifadesi, sağ taraftaki nesneyi sol taraftaki isme bağlar ya da var olan bağı değiştirir. Nesneyi kopyalamaz. Bu yüzden b = a yazdığınızda iki isim aynı nesneyi gösterir ve değiştirilebilir bir nesnede yapılan değişiklik her iki isimden de görünür:
a = [1, 2, 3]
b = a
b.append(4)
print(a)
print(a is b)
c = list(a)
c.append(5)
print(a, c)
print(a is c)
# çıktı: [1, 2, 3, 4]
# çıktı: True
# çıktı: [1, 2, 3, 4] [1, 2, 3, 4, 5]
# çıktı: Falselist(a) yeni bir liste nesnesi oluşturur, bu yüzden c üzerinde yapılan değişiklik a'yı etkilemez. İç içe listelerde bu kopya da yeterli olmayabilir, çünkü yalnızca dış liste kopyalanır; sığ ve derin kopya farkı liste metotları yazısında anlatılıyor.
Değiştirilemez bir nesnede durum farklıdır. Metne bir şey eklediğinizde mevcut metin değişmez; yeni bir metin nesnesi oluşur ve isim ona bağlanır. Eski isim hâlâ eski nesneyi gösterir:
s = "kedi"
t = s
s += "ler"
print(s, t)
print(s is t)
# çıktı: kediler kedi
# çıktı: FalseBir metnin tek bir karakterini değiştirmeye çalışırsanız Python 3.15.2 aşağıdaki hatayı verir (dosya yolu ornek.py olarak kısaltıldı):
s = "kedi"
s[0] = "K"Traceback (most recent call last):
File "ornek.py", line 2, in <module>
s[0] = "K"
~^^^
TypeError: 'str' object does not support item assignmentDeğiştirilemez kap içinde değiştirilebilir nesne
Veri modeli belgesi ince bir noktaya dikkat çeker: değiştirilemez bir kap, değiştirilebilir bir nesneye referans içerebilir. Tuple'ın hangi nesneleri içerdiği değişmez ama içindeki listenin kendisi değişebilir. Bu yüzden değiştirilemezlik, değerin hiç değişmemesiyle tam olarak aynı şey değildir:
t = (1, [2, 3])
t[1].append(4)
print(t)
# çıktı: (1, [2, 3, 4])Artırmalı atama: += her zaman aynı davranmaz
x += 1 çoğu zaman x = x + 1 ile aynı sonucu verir, ama tam olarak aynı değildir. Language Reference'a göre artırmalı atamada mümkün olduğunda işlem yerinde yapılır: yeni bir nesne oluşturmak yerine mevcut nesne değiştirilir. Listeler bunu destekler, tuple'lar desteklemez:
liste = [1, 2]
eski = id(liste)
liste += [3]
print(id(liste) == eski)
demet = (1, 2)
eski = id(demet)
demet += (3,)
print(id(demet) == eski)
# çıktı: True
# çıktı: FalseFark, aynı listeyi gösteren başka bir isim olduğunda önem kazanır: liste += [3] o ismi de etkiler, liste = liste + [3] ise etkilemez, çünkü ikincisi yeni bir liste oluşturur.
Fonksiyona değer geçirmek

Bir fonksiyona argüman verdiğinizde de aynı kural geçerlidir: parametre, çağıran taraftaki nesneye bağlanan yeni bir isimdir. Fonksiyon değiştirilebilir bir nesneyi yerinde değiştirirse değişiklik dışarıdan görünür; değiştirilemez bir nesneyi "değiştirmeye" çalışırsa yalnızca kendi yerel ismini yeni bir nesneye bağlar:
def ekle(oge, sepet):
sepet.append(oge)
alisveris = ["süt"]
ekle("ekmek", alisveris)
print(alisveris)
def artir(sayi):
sayi += 1
return sayi
n = 5
print(artir(n), n)
# çıktı: ['süt', 'ekmek']
# çıktı: 6 5Fonksiyonlar def yazısında, isimlerin hangi kapsamda arandığı ise global ve nonlocal yazısında anlatılıyor.
Dinamik tipleme: type() ve isinstance()
Python dinamik tipli bir dildir: bir ismi önce bir tamsayıya, sonra bir metne bağlayabilirsiniz. Değişken tanımlarken tip yazmazsınız; isteğe bağlı tip notları ise çalışma zamanında zorlanmaz (bkz. type hints).
deger = 5
print(type(deger))
deger = "beş"
print(type(deger))
# çıktı: <class 'int'>
# çıktı: <class 'str'>Bir değerin tipini sınamak için belgeler type() yerine isinstance() kullanmanızı önerir, çünkü isinstance() alt sınıfları da hesaba katar. İkinci argüman olarak bir tuple verirseniz birden çok tipi aynı anda sınayabilirsiniz. bool tipi int'in alt sınıfı olduğundan True bir tamsayı olarak da kabul edilir ve aritmetikte 1 gibi davranır:
print(isinstance(True, int))
print(True + True)
print(type(True) is bool)
print(isinstance(3.0, (int, float)))
print(type(3) == float)
# çıktı: True
# çıktı: 2
# çıktı: True
# çıktı: True
# çıktı: FalseNone: değerin yokluğu
None, tipinin tek nesnesi olan özel bir değerdir ve pek çok durumda "değer yok" anlamında kullanılır. Açıkça bir şey döndürmeyen fonksiyonlar None döndürür, doğruluk değeri de yanlıştır. Tek bir nesne olduğu için onu == ile değil is ile karşılaştırmak gerekir; Language Reference, PEP 8'in tekil nesneler için bu öneriyi yaptığını belirtir:
def selamla(isim):
print("Merhaba", isim)
sonuc = selamla("Ali")
print(sonuc)
print(sonuc is None)
# çıktı: Merhaba Ali
# çıktı: None
# çıktı: True== ile is arasındaki fark
== iki nesnenin değerini, is ise kimliğini karşılaştırır. İki ayrı liste aynı öğeleri içerdiğinde == doğru, is yanlış sonuç verir. Değiştirilemez tiplerde ise durum belirsizdir: belgelere göre a = 1; b = 1 sonrasında iki isim aynı nesneyi gösterebilir de göstermeyebilir de; bu uygulamaya bağlıdır ve buna güvenilmemelidir. CPython küçük tamsayıları önbellekte tutar ama sınırın geçmişte değiştiği de belgelerde not edilmiştir. Kısacası, değer karşılaştırması için her zaman ==, None gibi tekil nesneler için is kullanın. Python, bir sabitle is karşılaştırması yaptığınızda SyntaxWarning uyarısı da verir; örneği koşullar yazısında.
Çoklu atama, değer takası ve yıldızlı açma
Tek satırda birden çok isme değer atayabilirsiniz. Sağ taraf önce tamamen hesaplandığı için x, y = y, x iki değişkenin değerini geçici değişken olmadan takas eder. a = b = [] ise iki isme aynı nesneyi bağlar; bu, iki ayrı boş liste oluşturmaz. Yıldızlı hedef, kalan öğeleri bir listeye toplar:
x, y = 1, 2
x, y = y, x
print(x, y)
a = b = []
a.append("ortak")
print(b)
ilk, *kalan = [10, 20, 30]
print(ilk, kalan)
# çıktı: 2 1
# çıktı: ['ortak']
# çıktı: 10 [20, 30]Açma (unpacking) kurallarının tamamı tuple ve unpacking yazısında.
İsimlendirme kuralları
Bir isim harf, alt çizgi, rakam ve ASCII dışı "harf benzeri" karakterlerden oluşabilir; rakamla başlayamaz ve uzunluk sınırı yoktur. Büyük ve küçük harf farklıdır: Sayi ile sayi iki ayrı isimdir. if, for, class, None, True gibi 35 anahtar kelime isim olarak kullanılamaz. match, case, _, type ve 3.15 ile eklenen lazy ise yalnızca belirli bağlamlarda anahtar kelime gibi davranan "yumuşak anahtar kelimeler"dir; başka yerlerde isim olarak kullanılabilirler.
öğrenci_sayısı = 30
print(öğrenci_sayısı)
# çıktı: 30Türkçe karakterli isimler geçerlidir ve çalışır. Yine de belgeler, standart kütüphanenin isimlerde yalnızca ASCII karakter kullandığını ve taşınabilir kodun bu geleneği izlemesi gerektiğini belirtir. Bu seride örneklerde ASCII isimler (ogrenci_sayisi gibi) tercih ediyoruz. Kural dışı isimler söz dizimi hatası verir:
class = 5 File "ornek.py", line 1
class = 5
^
SyntaxError: invalid syntax2abc = 5 File "ornek.py", line 1
2abc = 5
^
SyntaxError: invalid decimal literalAlt çizgiyle başlayan isimlerin özel anlamları da vardır: _ad biçimindeki isimler from modul import * ile içe aktarılmaz, __ad__ biçimi yorumlayıcının kendi isimleri için ayrılmıştır ve belgelenmiş kullanım dışında bu kalıbı kendi isimlerinizde kullanmamanız gerekir.
Tanımsız isim ve del
Henüz bir değer bağlanmamış bir ismi kullanırsanız NameError alırsınız. Python 3.15 bu durumda benzer bir isim varsa öneride de bulunur, bu da yazım hatalarını bulmayı kolaylaştırır:
kullanici_adi = "deniz"
print(kullanici_ad)Traceback (most recent call last):
File "ornek.py", line 2, in <module>
print(kullanici_ad)
^^^^^^^^^^^^
NameError: name 'kullanici_ad' is not defined. Did you mean: 'kullanici_adi'?del x ifadesi nesneyi doğrudan silmez, x isminin bağını kaldırır. Sonrasında x kullanılırsa yine NameError oluşur. Nesnenin kendisi, kendisine ulaşan hiçbir referans kalmadığında çöp toplayıcı tarafından temizlenebilir; belgeler bu temizliğin zamanlamasına güvenmemenizi, dosya gibi kaynakları her zaman açıkça kapatmanızı önerir.
Python 3.15: frozendict
Python 3.15, yerleşik tiplere değiştirilemez bir sözlük olan frozendict tipini ekledi. Tıpkı tuple gibi, oluşturulduktan sonra öğe eklenemez ya da değiştirilemez:
ayar = frozendict(dil="tr", tema="koyu")
print(ayar["dil"])
ayar["dil"] = "en"
# çıktı: tr
# TypeError: 'frozendict' object does not support item assignmentAyrıntılar sözlük metotları ve Python 3.15 yenilikleri yazılarında.
Sık yapılan hatalar
![Sık yapılan hatalar: Kopyaladığını sanmak, a = b = [] ile iki liste beklemek, None ile == kullanmak, Tip kontrolünde type() kullanmak](/assets/blog/python-degiskenler-ve-veri-tipleri-b13.webp)
- Kopyaladığını sanmak:
b = abir kopya oluşturmaz. Bağımsız bir liste içinlist(a),a.copy()ya daa[:]kullanın. - a = b = [] ile iki liste beklemek: İki isim aynı listeyi gösterir. Ayrı listeler için
a, b = [], []yazın. - None ile == kullanmak:
if x == Noneyerineif x is Noneyazın. - Tip kontrolünde type() kullanmak:
type(x) == intalt sınıfları dışlar; çoğu durumdaisinstance(x, int)doğru seçimdir. - Yerleşik isimleri gölgelemek:
list = [1, 2]ya dastr = "a"yazmak hata vermez ama aynı kapsamdalist()vestr()fonksiyonlarına erişimi kaybettirir.
Sık Sorulan Sorular
Python'da değişken tanımlarken tip belirtmek gerekir mi?
Hayır. Tip, değere aittir ve atama sırasında otomatik belirlenir. İsterseniz sayi: int = 5 biçiminde tip notu ekleyebilirsiniz ama Python bunu çalışma zamanında denetlemez; bu notlar tip denetleyicileri ve okuyucular içindir.
Sabit (constant) tanımlayabilir miyim?
Python'da yeniden atanmayı engelleyen bir sabit anahtar kelimesi yoktur. Yaygın gelenek, değişmemesi gereken değerleri MAKS_DENEME = 3 gibi büyük harfle yazmaktır; bu yalnızca okuyucuya verilen bir işarettir. Sabit değer kümeleri için Enum daha güçlü bir seçenektir.
id() değeri neden her çalıştırmada farklı?
CPython'da id() nesnenin bellek adresidir ve nesneler her çalıştırmada farklı adreslere yerleşebilir. Kimlik yalnızca nesnenin yaşadığı süre boyunca anlamlıdır; değerini kaydetmek ya da karşılaştırmak için kullanmayın.
Boş değer için None mı, boş metin mi kullanmalıyım?
"Henüz değer yok" anlamı için None daha açıktır, çünkü boş metin geçerli bir değer de olabilir. Ancak ikisinin de doğruluk değeri yanlış olduğundan if not x ikisini ayırt etmez; ayırt etmeniz gerekiyorsa is None kontrolü kullanın (bkz. koşullar).
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Python öğrenme rehberi · Sayılar · String metotları · Liste metotları · Kapsam