biotech Django & Python

Python'da Veri Tipleri: Mutable vs Immutable ve 2026 Modern Kullanım

AK
Ali Kasımoğlu
07 May 2021 schedule 5 dk okuma
Python'da {p}Veri Tipleri{/p}: Mutable vs Immutable ve 2026 Modern Kullanım
analytics

Insight Density

groups Hedef Kitle: Deneyimli
65 Score

Teknik karmaşıklık ve içerik yoğunluğuna göre hesaplandı.

Son güncelleme: Nisan 2026 · AnomixLabs Teknik Ekibi

Python'da her şey bir nesnedir. Bu nesnelerin değiştirilebilir olup olmadığını bilmek, beklenmedik bug'lardan ve performans sorunlarından korur — ve daha iyi Python kodu yazmanızı sağlar.

1. Nesne Kimliği: id() ile Görmek

Python'da her nesnenin benzersiz bir kimliği (bellek adresi) vardır. Immutable nesneler 'değiştirildiğinde' yeni nesne oluşurken, mutable nesneler aynı kimliği korur:

x = 42
print(id(x))    # örn: 140234567890
x = x + 1
print(id(x))    # FARKLI id — yeni nesne oluştu

liste = [1, 2, 3]
print(id(liste))  # örn: 140234599999
liste.append(4)
print(id(liste))  # AYNI id — nesne değişti, kimlik aynı

2. CPython Integer Interning

CPython, -5 ile 256 arasındaki tamsayıları önceden oluşturur ve önbelleğe alır (interning). Bu aralıktaki sayılar her kullanımda aynı nesneyi paylaşır:

a = 100; b = 100
print(a is b)    # True — aynı nesne (interned)

a = 1000; b = 1000
print(a is b)    # False — farklı nesneler (>256)

# Bu yüzden integer karşılaştırmada == kullanın, is değil
# is operatörü kimlik kontrolü içindir, değer değil

3. Immutable Tipler

Oluşturulduktan sonra içerikleri değiştirilemez. Her 'değişiklik' yeni nesne oluşturur:

Python mutable ve immutable veri tipleri karşılaştırması

# int, float, complex, bool
n = 10           # immutable int
b = True         # bool, int'in alt sınıfı

# str — karakter değiştirilemez
s = 'merhaba'
s[0] = 'M'       # TypeError!

# tuple — öğe değiştirilemez
t = (1, 2, 3)
t[0] = 99        # TypeError!

# frozenset — set'in immutable versiyonu
fs = frozenset({1, 2, 3})
fs.add(4)        # AttributeError!

# bytes — bytearray'in immutable versiyonu
b = b'hello'
b[0] = 72        # TypeError!

4. Mutable Tipler

# list
l = [1, 2, 3]
l.append(4)     # [1, 2, 3, 4] — aynı nesne
l[0] = 99       # [99, 2, 3, 4] — aynı nesne

# dict
d = {'isim': 'Ali'}
d['yas'] = 30   # {'isim': 'Ali', 'yas': 30}

# set
s = {1, 2, 3}
s.add(4)        # {1, 2, 3, 4}

# bytearray — mutable bytes
ba = bytearray(b'hello')
ba[0] = 72      # bytearray(b'Hello')

5. Kritik Tuzak: Mutable Varsayılan Argüman

Python'ın en sık karşılaşılan bug kaynaklarından biri. Fonksiyon tanımında mutable varsayılan argüman kullanmak, tüm çağrılar arasında paylaşılan tek bir nesne oluşturur:

# YANLIŞ — fonksiyon tanımında bir kez oluşturulur, paylaşılır!
def ekle(eleman, liste=[]):
    liste.append(eleman)
    return liste

print(ekle(1))  # [1]
print(ekle(2))  # [1, 2]  ← Sürpriz!
print(ekle(3))  # [1, 2, 3]  ← Hâlâ aynı liste!

# DOĞRU — None ile varsayılan
def ekle_dogru(eleman, liste=None):
    if liste is None:
        liste = []
    liste.append(eleman)
    return liste

6. Shallow Copy vs Deep Copy

import copy

original = [[1, 2], [3, 4]]

# Shallow copy — iç listeler paylaşılır!
shallow = original.copy()  # veya original[:]
shallow[0].append(99)
print(original[0])  # [1, 2, 99] ← etkilendi!

# Deep copy — tamamen bağımsız kopya
original2 = [[1, 2], [3, 4]]
deep = copy.deepcopy(original2)
deep[0].append(99)
print(original2[0])  # [1, 2] ← etkilenmedi

7. Bellek Kullanımı Karşılaştırması

import sys

# list vs tuple bellek boyutu (Python 3.12)
liste = [1, 2, 3, 4, 5]
tuple_ = (1, 2, 3, 4, 5)

print(sys.getsizeof(liste))   # 120 bytes
print(sys.getsizeof(tuple_))  # 80 bytes  ← %33 daha küçük

# __slots__ ile bellek optimizasyonu
class Normal:
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Optimize:
    __slots__ = ['x', 'y']
    def __init__(self, x, y):
        self.x = x
        self.y = y

# Binlerce örnek oluşturulduğunda __slots__ ~%50 bellek tasarrufu

8. Python 3.10+ Tip İpuçları

# Python 3.10+ — | operatörü ile union type
def isle(deger: int | str) -> str:
    return str(deger)

# list, dict, tuple tip ipuçları (3.9+ built-in)
isimler: list[str] = ['Ali', 'Ayşe']
puan_tablosu: dict[str, int] = {'Ali': 95}

# Python 3.12 — type alias syntax
type Vector = list[float]
type Matrix = list[Vector]

def dot_product(v1: Vector, v2: Vector) -> float:
    return sum(a * b for a, b in zip(v1, v2))

9. Walrus Operatörü (:=) — Python 3.8+

# Atama ifadesi — koşulda hem ata hem kullan
while chunk := dosya.read(8192):
    isle(chunk)

# Liste comprehension'da tekrarlı hesaplamayı önle
sonuclar = [y for x in veriler if (y := islem(x)) > 0]

# re.match ile yaygın kullanım
import re
if m := re.match(r'(\d+)-(\d+)', metin):
    baslangic, bitis = m.group(1), m.group(2)

10. Match Statement — Python 3.10+

def http_mesaj(kod: int) -> str:
    match kod:
        case 200: return 'OK'
        case 404: return 'Bulunamadı'
        case 500: return 'Sunucu Hatası'
        case _: return 'Bilinmeyen'

# Yapısal eşleşme (structural pattern matching)
def isle_komut(komut):
    match komut:
        case {'action': 'ekle', 'item': item}:
            return f'{item} eklendi'
        case {'action': 'sil', 'item': item}:
            return f'{item} silindi'
        case _:
            return 'Bilinmeyen komut'

11. dataclass, TypedDict ve frozen

from dataclasses import dataclass, field
from typing import TypedDict

# dataclass — otomatik __init__, __repr__, __eq__
@dataclass
class Kullanici:
    isim: str
    yas: int
    roller: list[str] = field(default_factory=list)

# frozen=True — immutable dataclass (hash'lenebilir)
@dataclass(frozen=True)
class Koordinat:
    x: float
    y: float
    # x = 5 → FrozenInstanceError!

# TypedDict — dict için tip güvencesi
class Film(TypedDict):
    baslik: str
    yil: int
    puan: float

Özet

Immutable: int, float, complex, bool, str, bytes, tuple, frozenset — hash'lenebilir, dict key olarak kullanılabilir, thread-safe.
Mutable: list, dict, set, bytearray — yerinde değişir, dict key olarak kullanılamaz.
Modern Python'da: dataclass ile tip-safe veri yapıları, TypedDict ile dict güvencesi, match ile temiz koşul mantığı, := walrus ile akıcı ifadeler, __slots__ ile bellek optimizasyonu.

Sıkça Sorulan Sorular

Tuple neden list'ten daha hızlı? expand_more
Tuple immutable olduğu için Python interpreter onu sabit bellek bloğuna yerleştirir. List ise dinamik büyüme için ekstra bellek yönetimi gerektirir. sys.getsizeof() ile görebilirsiniz: 5 elemanlı tuple 80 byte, list 120 byte. Değişmeyecek veri koleksiyonları için tuple tercih edin — özellikle çok sayıda örnek oluşturulduğunda bellek farkı önem kazanır.
dataclass ile NamedTuple arasındaki fark nedir? expand_more
NamedTuple immutable ve tuple alt sınıfı — tuple gibi index erişimi destekler, hashing mümkündür. dataclass ise mutable (frozen=True ile immutable yapılabilir), sınıf hiyerarşisine katılır, __post_init__ hook'u destekler ve daha esnek metodlar eklenebilir. API response, DB row gibi salt-okunur veriler için NamedTuple; business logic nesneleri için dataclass uygundur.
Python'da gerçekten her şey nesne mi? expand_more
Evet. Python'da int, float, str, fonksiyon, sınıf, modül — hepsi nesne. Bunu doğrulamak için: type(42).__mro__ ile int'in miras zincirini, dir(42) ile int nesnesinin metodlarını görebilirsiniz. Fonksiyonlar bile birinci sınıf nesnedir: başka fonksiyona parametre olarak geçilebilir, bir listede saklanabilir.
list comprehension mı, generator mı tercih edilmeli? expand_more
Tüm elemanları belleğe yüklemek yerine birer birer işleyecekseniz generator tercih edin. list comprehension ([x*2 for x in range(1_000_000)]) tüm listeyi belleğe yükler; generator ((x*2 for x in range(1_000_000))) sadece istendiğinde hesaplar. Büyük veri setleri veya dosya satırlarını işlerken generator bellek kullanımını dramatik biçimde düşürür.
frozenset hangi durumlarda kullanılır? expand_more
frozenset, set'in immutable versiyonu. Dict key olarak kullanılabilir (set kullanılamaz). İki kullanım senaryosu: 1) Hash'lenebilir (immutable) küme gerektiğinde — ör: tuple içinde küme saklamak. 2) Değişmemesi gereken sabit kümeleri tanımlamak — ör: ALLOWED_EXTENSIONS = frozenset({'pdf', 'jpg', 'png'}). Yanlışlıkla değiştirme girişiminde AttributeError fırlatır.
TypedDict vs dataclass: hangisi ne zaman? expand_more
TypedDict, mevcut dict yapısına tip güvencesi ekler — dict olarak kullanılabilir, JSON serialize/deserialize uyumlu. dataclass ise gerçek bir sınıf — metodlar eklenebilir, miras alınabilir, frozen yapılabilir. API yanıtlarını, JSON verisini veya dış veri kaynaklarını temsil etmek için TypedDict; business logic nesneleri ve methodlu modeller için dataclass tercih edin.
Python 3.12 type alias syntax neden önemli? expand_more
Python 3.12 ile gelen 'type Vector = list[float]' syntax, PEP 695 ile eklendi. Eski 'Vector = list[float]' atamak yerine açık bir type alias oluşturur — IDE'ler ve mypy tarafından daha iyi anlaşılır. TypeAlias annotation'a gerek kalmaz. Generic type alias da desteklenir: 'type Stack[T] = list[T]'. 2026'da Python 3.12+ kullanan projeler için tercih edilmesi önerilen syntax.
Etiketler: #Python #Veri Tipleri #Mutable #Immutable #Type Hints #dataclass #TypedDict #Walrus #Python 3.12
share

Bu Makaleyi Paylaş

Bilgiyi ağınızla paylaşarak bize destek olun.

AK

Ali Kasımoğlu

Full-stack Geliştirici & AnomixLabs Kurucusu

Python ve Django ekosisteminde uzmanlaşmış bir yazılım geliştirici. Modern web mimarileri, yapay zeka entegrasyonları ve minimalist kullanıcı deneyimleri üzerine odaklanıyor. AnomixLabs çatısı altında, karmaşık problemleri yalın ve etkili dijital çözümlere dönüştürmeyi hedefliyor.

psychology
psychology

Makale Hakkında Soru Sorun

AnomixAI · Makale içeriğine dayalı yanıtlar

5 soru hakkı
Yalnızca makale içeriği hakkında 0/500
forward_to_inbox

Geleceği Çözümleyin.

Enterprise yapay zeka, yazılım mimarisi ve dijital dönüşüm üzerine aylık brifingi alan 5.000+ mühendis ve kurucuya katılın. Spam yok.