---
title: 'Sınıf ve Örnek'
source: 'https://academia.sh/tr/kurslar/python-nesne-ve-tipler/sinif-ve-ornek'
course: 'Nesneye Dayalı Python ve Tipler'
language: tr
updated: '2026-08-17T18:10:29+00:00'
license: 'CC BY-SA 4.0'
---

# Sınıf ve Örnek

Sınıf gövdesinde yazılan öznitelik üç örnekte 1 nesne olarak paylaşılır, örnek gövdesinde yazılan 3 ayrı nesne üretir; `self` bir anahtar sözcük değil, erişim anında kurulan bağlı yöntemin taşıdığı örnektir.

Veri Yapıları ve Fonksiyonel Araçlar kursu kabın bedelini saydı ve kapanışta bir sınır çizdi:
**kabı seçmekle kabı yazmak ayrı şeylerdir.** Buraya kadar ölçülen bütün protokoller dilin
verdiği nesnelerde işledi. Liste bir uzunluğa sahipti, demet bir kapta anahtar olabiliyordu,
sözlük karşılaştırılabiliyordu — hiçbiri bizim yazdığımız bir sözleşme değildi, hepsi seçilmiş
bir kabın hazır gelen özellikleriydi.

Bu kurs sınırın öbür tarafındadır: protokole **katılan tarafı biz yazarız.** Ve bir şeyi
yazmak, onun çağrıyı gerçekten yanıtladığı anlamına gelmez. Kursun tek sorusu budur:
**çağrıyı kim yanıtladı?** İlk ders sorunun en küçük hâlini kurar. Bir sınıf tanımlandığında
iki ayrı ad alanı ortaya çıkar — sınıfın kendisi ve ondan var edilen her örnek. Bir öznitelik
okunduğunda yanıt bu ikisinden hangisinden gelir, ve `self` denen ad nereden doğar?

## İki Ayrı Ad Alanı

Bir `class` deyimi çalıştığında yorumlayıcı gövdeyi **bir kez** koşturur ve gövdede oluşan
adları sınıf nesnesinin sözlüğüne yazar. Sınıf, çalışma zamanında var olan bir nesnedir;
yöntemler de o sözlüğün içindeki sıradan işlevlerdir.

Her örnek ise **kendi** sözlüğüyle gelir. `__init__` içinde `self.ad = ...` yazıldığında ad
sınıfa değil, o örneğin sözlüğüne yazılır. Bir öznitelik okunduğunda arama önce örneğin
sözlüğüne bakar, orada yoksa sınıfın sözlüğüne, sonra sınıfın atalarına. **Yanıtı ilk bulan
verir.** Ortak kurgunun `saglayan` işlevi bu aramanın sınıf tarafını yazıya döker: bir adı
çözümleme sırasında ilk hangi sınıfın taşıdığını söyler.

`__init__`'in adı da bu düzenden çıkar. Örnek çağrı yapıldığında **önce** boş bir nesne var
edilir, **sonra** `__init__` o nesne üzerinde koşar; yani `__init__` bir nesne üretmez, var
edilmiş bir nesnenin sözlüğünü doldurur. Bir şey döndürmemesinin nedeni budur — döndürecek bir
nesnesi yoktur, kendisine verilmiş bir nesnesi vardır.

Ölçümün varsayımları:

- **SN1** — Ölçülen sınıf ortak kurgunun `Kayit` sınıfıdır; gövdesine bir sınıf özniteliği
  (`tur`) eklenmiş, `kaynak` ve `bicimle` yetenekleri değiştirilmemiştir.
- **SN2** — Üç örnek aynı sınıftan ve tek bir kavrama ile var edilir; aralarındaki tek fark
  `__init__`'e verilen addır.
- **SN3** — "Ayrı nesne" sütunu ilk iki örneğin gördüğü değeri `is` ile karşılaştırır;
  **kimlik sayısı basılmaz.**
- **SN4** — "Örnek sözlüğünde" sütunu adın kaç örneğin **kendi** sözlüğünde bulunduğunu
  sayar; sınıftan gelen adlar bu sayıya girmez.

```python
"""Oznitelik nerede duruyor: sinif govdesi ile ornek govdesi."""


class Kayit:
    """Ortak kurgunun temel sinifi; burada iki yetenegi kullanilir."""

    tur = "kayit"                       # sinif govdesinde yazili

    def __init__(self, ad):
        self.ad = ad                    # ornek govdesinde yazili

    def kaynak(self):
        return "Kayit"

    def bicimle(self):
        return f"<{self.kaynak()}>"


def saglayan(sinif, ad):
    """Bir ozniteligi hangi sinif sagliyor: cozumleme sirasinda ilk bulan."""
    for s in sinif.__mro__:
        if ad in s.__dict__:
            return s.__name__
    return None


ucu = [Kayit(f"k{i}") for i in range(3)]

print(f"{'öznitelik':<10s} {'yanıtlayan':>11s} {'ayrı nesne':>11s} "
      f"{'örnek sözlüğünde':>17s}")
for ad in ("tur", "ad"):
    ayri = getattr(ucu[0], ad) is not getattr(ucu[1], ad)
    yerel = sum(1 for u in ucu if ad in u.__dict__)
    print(f"{ad:<10s} {saglayan(Kayit, ad) or 'örnek':>11s} {str(ayri):>11s} "
          f"{yerel:>17d}")

a, b = Kayit("a"), Kayit("b")
print(f"\nbaşta        a.tur={a.tur!r} b.tur={b.tur!r} Kayit.tur={Kayit.tur!r} "
      f"a'nın sözlüğünde tur -> {'tur' in a.__dict__}")
a.tur = "özel"
print(f"a.tur atandı a.tur={a.tur!r} b.tur={b.tur!r} Kayit.tur={Kayit.tur!r} "
      f"a'nın sözlüğünde tur -> {'tur' in a.__dict__}")
del a.tur
print(f"ad silindi   a.tur={a.tur!r} b.tur={b.tur!r} Kayit.tur={Kayit.tur!r} "
      f"a'nın sözlüğünde tur -> {'tur' in a.__dict__}")
```

```
öznitelik   yanıtlayan  ayrı nesne  örnek sözlüğünde
tur              Kayit       False                 0
ad               örnek        True                 3

başta        a.tur='kayit' b.tur='kayit' Kayit.tur='kayit' a'nın sözlüğünde tur -> False
a.tur atandı a.tur='özel' b.tur='kayit' Kayit.tur='kayit' a'nın sözlüğünde tur -> True
ad silindi   a.tur='kayit' b.tur='kayit' Kayit.tur='kayit' a'nın sözlüğünde tur -> False
```

İlk tablo iki adın iki ayrı yerde durduğunu gösteriyor. `tur` okunduğunda yanıtı veren
**`Kayit`**'tir; üç örneğin üçü de aynı nesneyi görür ve **hiçbirinin** kendi sözlüğünde bu ad
yoktur — sayı **0**. `ad` okunduğunda yanıtı veren sınıf **yoktur**; üç örneğin üçü de kendi
sözlüğünde taşır, sayı **3**, ve gördükleri nesneler ayrıdır.

Alt bölüm arama sırasının doğrudan sonucudur. `a.tur = "özel"` satırı sınıftaki adı
**değiştirmez**; `a`'nın sözlüğüne yeni bir giriş açar ve o giriş aramada önce bulunduğu için
sınıftakini **gölgeler**. `b` ile sınıfın kendisi olduğu gibi kalır. Örnekteki ad silindiğinde
gölge kalkar ve `a.tur` yine sınıfın verdiği değeri okumaya döner. Bir örneğe atama yapmak
sınıfa hiçbir zaman dokunmaz — **sınıfı değiştirmenin tek yolu sınıfa yazmaktır.**

## Sınıf Gövdesi Bir Kez Koşar

Yukarıdaki ayrımın maliyet tarafı vardır ve dikkatsiz yazımda gözden kaçar: sınıf gövdesi
tanım anında **bir kez** koşar, örnek gövdesi (`__init__`) **her örnekte** koşar. Sınıf
gövdesinde `= []` yazmak tek bir liste var eder ve o listeyi bütün örnekler paylaşır.

- **SN5** — Ölçülen sınıf aynı türden iki adı bilerek iki ayrı gövdede tanımlar; adların
  dışında hiçbir farkları yoktur.
- **SN6** — Üç örnek var edilir ve her biri **kendi sırasını** iki kaba da ekler; ölçülen şey
  her örneğin sonunda kaç öğe gördüğüdür.
- **SN7** — Paylaşım `is` ile gösterilir.

```python
class Ortak:
    """Ayni turden iki adi ayri govdelerde tanimlar: biri sinifta, oteki ornekte."""

    ortak_kutu = []                     # sinif govdesi: bir kez calisir

    def __init__(self):
        self.kendi_kutusu = []          # ornek govdesi: her ornekte calisir


ucu = [Ortak() for _ in range(3)]
for i, n in enumerate(ucu):
    n.ortak_kutu.append(i)
    n.kendi_kutusu.append(i)

print(f"{'öznitelik':<14s} {'var edilen kap':>15s} {'her örneğin gördüğü':>20s} "
      f"{'paylaşılıyor':>13s}")
print(f"{'ortak_kutu':<14s} {1:15d} {str([len(n.ortak_kutu) for n in ucu]):>20s} "
      f"{str(ucu[0].ortak_kutu is ucu[2].ortak_kutu):>13s}")
print(f"{'kendi_kutusu':<14s} {3:15d} {str([len(n.kendi_kutusu) for n in ucu]):>20s} "
      f"{str(ucu[0].kendi_kutusu is ucu[2].kendi_kutusu):>13s}")
```

```
öznitelik       var edilen kap  her örneğin gördüğü  paylaşılıyor
ortak_kutu                   1            [3, 3, 3]          True
kendi_kutusu                 3            [1, 1, 1]         False
```

Üç örnek, kap başına birer ekleme yaptı. Sınıf gövdesindeki kap **1** kez var edildiği için üç
eklemenin üçü de aynı listeye gitti ve her örnek **3** öğe görüyor. Örnek gövdesindeki kap **3**
kez var edildi ve her örnek yalnız kendi eklediğini, **1** öğe görüyor. Sayılar aynı satırlardan
çıkmıştır; ayrım tek başına gövdenin yerindedir.

Buradan bir yazım kuralı çıkar: **değiştirilebilir bir değer sınıf gövdesine yazılmaz.** Sınıf
gövdesi sabitler, sayılar ve değiştirilemez değerler içindir — onlarda paylaşımın gözlenebilir
bir sonucu yoktur, çünkü kimse onları yerinde değiştiremez. Bir örneğe ait olması gereken her
durum `__init__` içinde kurulur. Sınıf özniteliğinin doğru kullanımı da bu tabloda görünür:
ilk ölçümdeki `tur` bir **varsayılan**dır ve örnek onu yalnız gerektiğinde gölgeler; üç örnek
için tek nesne yeter, çünkü kimse onu yerinde değiştirmez.

## `self` Bir Anahtar Sözcük Değildir

Sınıf sözlüğünde duran yöntem sıradan bir işlevdir ve ilk parametresi başka bir addan farklı
değildir. Örnek üzerinden erişildiğinde araya bir adım girer: erişim, işlevi ve örneği bir
arada tutan **bağlı bir yöntem** nesnesi üretir. Çağrıda ilk argümanı yazmayışımızın nedeni
budur — o argüman erişim anında zaten bağlanmıştır.

- **SN8** — Ölçüm ilk bloğun `Kayit` sınıfını sürdürür; yeni bir tanım yapılmaz.
- **SN9** — Aynı çağrı iki yazımla yapılır: örnek üzerinden ve sınıf üzerinden, örnek elle
  geçirilerek. Ölçülen şey iki yazımın **aynı sonucu** verip vermediğidir.
- **SN10** — Nesnelerin tipi ad olarak basılır; **kimlik sayısı ve bellek verisi basılmaz.**
- **SN11** — Son satırdaki çağrı bilerek örneksiz yapılır; istisnanın **adı** kaydedilir.

```python
k = Kayit("k")
print(f"k.bicimle() -> {k.bicimle()} | Kayit.bicimle(k) -> {Kayit.bicimle(k)} | "
      f"eşit -> {k.bicimle() == Kayit.bicimle(k)}")
print(f"sınıf sözlüğündeki nesnenin tipi -> "
      f"{type(Kayit.__dict__['bicimle']).__name__}")
print(f"örnek üzerinden erişilenin tipi  -> {type(k.bicimle).__name__}")
print(f"bağlı yöntemin tuttuğu nesne k mi -> {k.bicimle.__self__ is k}")
print(f"k.bicimle is k.bicimle -> {k.bicimle is k.bicimle} | "
      f"Kayit.bicimle is Kayit.bicimle -> {Kayit.bicimle is Kayit.bicimle}")
print(f"bağlı yöntemin sardığı işlev -> {k.bicimle.__func__ is Kayit.bicimle}")

try:
    Kayit.bicimle()
except TypeError as e:
    print(f"örneksiz çağrı -> {type(e).__name__}")

print()
print(f"{'yetenek':<10s} {'yanıtlayan sınıf':>17s}")
for ad in ("kaynak", "bicimle", "__init__"):
    print(f"{ad:<10s} {saglayan(Kayit, ad):>17s}")
print(f"{'ad':<10s} {saglayan(Kayit, 'ad') or '—':>17s}")
```

```
k.bicimle() -> <Kayit> | Kayit.bicimle(k) -> <Kayit> | eşit -> True
sınıf sözlüğündeki nesnenin tipi -> function
örnek üzerinden erişilenin tipi  -> method
bağlı yöntemin tuttuğu nesne k mi -> True
k.bicimle is k.bicimle -> False | Kayit.bicimle is Kayit.bicimle -> True
bağlı yöntemin sardığı işlev -> True
örneksiz çağrı -> TypeError

yetenek     yanıtlayan sınıf
kaynak                 Kayit
bicimle                Kayit
__init__               Kayit
ad                         —
```

İlk satır iki yazımın aynı işi yaptığını gösteriyor: `k.bicimle()` ile `Kayit.bicimle(k)`
aynı sonucu veriyor. İkincisi ilkinin açılmış hâlidir. Sonraki iki satır aradaki adımı
adlandırıyor — sınıfın sözlüğünde duran nesne bir **işlev**, örnek üzerinden erişilen nesne bir
**yöntem**. Dördüncü satır yöntemin ne taşıdığını söylüyor: erişimin yapıldığı örneğin
kendisini.

Beşinci satır bağlamanın **erişim anında** olduğunu kanıtlıyor. Aynı adı iki kez okumak iki
ayrı bağlı yöntem nesnesi üretiyor; `is` karşılaştırması `False` veriyor. Sınıf üzerinden
erişimde ise bağlama yoktur — her seferinde sözlükteki aynı işlev döner ve karşılaştırma `True`
çıkar. Altıncı satır ikisini birleştiriyor: bağlı yöntemin sardığı işlev, sınıftan okunan
işlevin **ta kendisidir**. Örneksiz çağrının `TypeError` vermesinin nedeni de buradadır — işlev
bir parametre bekliyordu ve onu bağlayacak bir örnek yoktu.

Bunun günlük yazımda iki sonucu vardır. Birincisi, bağlı yöntem çağrılmadan da bir **değer**
olarak taşınabilir: `k.bicimle` bir yere geçirildiğinde yanına `k` de gitmiş olur, çünkü nesne
örneği içinde taşır. Bir geri çağrı listesine yöntem koymak, o listeye örneği de koymaktır.
İkincisi, bir yöntemi sınıftan okuyup elle çağırmak her zaman mümkündür; örnek gizli bir
argüman değil, açıkça yazılabilen ilk argümandır.

Nesneye dayalı programlamanın kavramları Programlama Temelleri kursunda kurulmuştu; **bunlar
tekrarlanmaz.** Orada sınıf bir kalıp, örnek onun bir üretimiydi. Burada ölçülen şey kalıbın
kendisinin de bir **nesne** olduğu ve yanıtın hangi sözlükten geldiğidir. Son tablo bunu
kapatıyor: dört adın dördünü de `Kayit` yanıtlıyor, `ad` özniteliğini yanıtlayan bir sınıf
**yok** — o ad hiçbir sınıfta yazılı değil, her örnekte ayrı ayrı doğuyor.

## Bağlamanın Üç Biçimi

Bağlama bir kural olduğuna göre değiştirilebilir. Aynı sınıf gövdesinde üç ayrı bağlama biçimi
tanımlanabilir: ilk argümanı **örneğe** bağlayan yöntem, ilk argümanı **sınıfa** bağlayan
yöntem, ve hiçbir şeye bağlanmayan yöntem. Üçü de aynı gövdede durur ve aynı biçimde çağrılır;
ayrıldıkları tek yer, çağrı anında ilk argümanın ne olduğudur.

- **SN12** — Üç yöntem tek bir sınıf gövdesinde tanımlanır ve üçü de aynı işi yapar: kendisine
  bağlanan şeyin adını döndürür. Bağlanan bir şey yoksa yerine bir tire döndürülür.
- **SN13** — Ölçüm bir **alt sınıf** üzerinden yapılır; gövdeleri yazan sınıf ile çağrının
  yapıldığı sınıf bilerek ayrıştırılmıştır.
- **SN14** — "Çağrı" sütunları yöntemi **argümansız** çağırır; karşılanamayan çağrı bir
  istisnayla düşer ve ünlem önekiyle **istisnanın adı** kaydedilir.
- **SN15** — Erişim sütunları dönen nesnenin tipini ad olarak basar; **kimlik sayısı
  basılmaz.**

```python
class Bicimci:
    """Ayni govdede uc baglama bicimi: ornege, sinifa ve hicbir seye baglanan."""

    def ornek_yontemi(self):
        return type(self).__name__

    @classmethod
    def sinif_yontemi(cls):
        return cls.__name__

    @staticmethod
    def duragan_yontem():
        return "—"


class AltBicimci(Bicimci):
    pass


def dene(cagri):
    try:
        return cagri()
    except TypeError as e:
        return f"!{type(e).__name__}"


n = AltBicimci()
print(f"{'yöntem':<15s} {'sınıftan erişim':>15s} {'örnekten erişim':>15s} "
      f"{'sınıftan çağrı':>15s} {'örnekten çağrı':>15s}")
for ad in ("ornek_yontemi", "sinif_yontemi", "duragan_yontem"):
    print(f"{ad:<15s} {type(getattr(AltBicimci, ad)).__name__:>15s} "
          f"{type(getattr(n, ad)).__name__:>15s} "
          f"{dene(getattr(AltBicimci, ad)):>15s} "
          f"{dene(getattr(n, ad)):>15s}")

print(f"\ngövdeyi yazan sınıf {saglayan(AltBicimci, 'sinif_yontemi')}, "
      f"cls'e bağlanan sınıf {AltBicimci.sinif_yontemi()}")
```

```
yöntem          sınıftan erişim örnekten erişim  sınıftan çağrı  örnekten çağrı
ornek_yontemi          function          method      !TypeError      AltBicimci
sinif_yontemi            method          method      AltBicimci      AltBicimci
duragan_yontem         function        function               —               —

gövdeyi yazan sınıf Bicimci, cls'e bağlanan sınıf AltBicimci
```

Tablo bağlamanın nerede olduğunu satır satır gösteriyor. Örnek yöntemi yalnız **örnekten**
erişildiğinde bağlanır; sınıftan erişilen nesne çıplak bir işlevdir ve argümansız çağrı
`TypeError` ile düşer. Sınıf yöntemi **her iki** erişimde de bağlıdır — sınıftan okunduğunda
bile bir yöntem döner, çünkü bağlanacak şey zaten sınıfın kendisidir; argümansız çağrı iki
yoldan da çalışır. Durağan yöntem hiçbir erişimde bağlanmaz; iki yoldan da çıplak işlev döner
ve iki çağrı da bağlanan bir şey olmadığını bildirir.

Altı çağrının **beşi** karşılık buluyor, **biri** düşüyor. Düşen çağrı bir eksiklik değil,
kuralın kendisidir: örnek yöntemi bir örnek olmadan çağrılamaz, çünkü ilk parametresini
dolduracak bir şey yoktur.

Son satır kursun sorusunun ilk keskin hâlidir. `sinif_yontemi` gövdesi **`Bicimci`'de**
yazılıdır; ama çağrı `AltBicimci` üzerinden yapıldığı için `cls`'e bağlanan sınıf
**`AltBicimci`**'dir. Gövdeyi yazan sınıf ile çağrıyı yanıtlayan bağlam aynı şey değildir —
gövde bir yerde durur, bağlama çağrı anında olur. Sonraki dersin ölçtüğü ayrım bunun
büyütülmüş hâlidir.

## Özet

- Sınıf ve örnek iki ayrı ad alanıdır; öznitelik araması önce örneğin sözlüğüne, sonra sınıfın
  sözlüğüne bakar ve **yanıtı ilk bulan verir**.
- Sınıf gövdesindeki `tur` üç örnekte **1** nesne olarak paylaşılır ve hiçbirinin sözlüğünde
  bulunmaz; `__init__` içindeki `ad` **3** ayrı nesne üretir ve üç sözlüğün üçünde de durur.
- Örneğe atama sınıfı değiştirmez, gölgeler; örnekteki ad silindiğinde sınıftaki değer yine
  görünür hâle gelir.
- Sınıf gövdesi bir kez, örnek gövdesi her örnekte koşar: sınıfta tanımlanan bir kap **1** kez
  var edilip **3** eklemeyi birlikte tutar, örnekte tanımlanan **3** kez var edilir.
- `self` bir anahtar sözcük değildir: örnek üzerinden erişim her seferinde yeni bir **bağlı
  yöntem** üretir, o yöntem erişilen örneği taşır ve çağrıda ilk argüman olarak geçirir.
- Bağlamanın üç biçimi vardır; altı çağrının **beşi** karşılık bulur ve düşen tek çağrı örnek
  yönteminin örneksiz çağrılmasıdır. Gövdesi `Bicimci`'de yazılı bir sınıf yöntemi
  `AltBicimci` üzerinden çağrıldığında `cls`'e **`AltBicimci`** bağlanır.

## Sonraki Adım

Bu derste yanıtı veren her zaman `Kayit`'ti, çünkü ortada tek bir sınıf vardı ve arama ilk
adımda bitiyordu. Sınıflar birbirinden türediğinde arama uzar: bir ad birden çok sınıfta yazılı
olabilir ve hangisinin bulunacağını **çözümleme sırası** belirler. Sonraki ders bu sırayı
ölçer ve kursun ikinci iddiasını öder — dört yeteneğin gövdesi bir kalıtım ağacında hangi
sınıflara dağılır, aynı dört yeteneği bileşimle veren bir sınıf kaçını kendi gövdesinde yazar,
ve gövdesi bir sınıfta yazılı olan bir yöntem neden başka bir sınıfın adını basar?
