Python’da nesne zihinsel modeli: kimlik, değer, durum ve referans

Bu haftadan itibaren dersin ana konusu nesne tabanlı programlamadır. Python’da programın kullandığı her değer, yani her sayı, metin, liste ve sözlük, bir nesnedir (object). Kendi nesne türlerimizi tanımlamak için kullanacağımız class deyimine gelecek hafta geçeceğiz. Bu hafta değişken adlarının nesnelere nasıl bağlandığını ve aynı nesneye iki farklı addan erişmenin ne sonuç doğurduğunu göreceğiz. 3. haftada listelerle yaptığımız deneyleri bu kez bir kaydın üzerinde yineleyeceğiz.

Bu sayfadaki kod hücreleri kendiliğinden çalışmaz. Her hücrede önce çıktıyı tahmin edin, sonra Run Code düğmesine basın. Kodu değiştirip yeniden çalıştırabilir, Start Over ile ilk hâline döndürebilirsiniz.

Bu bölümün kapsamı

NoteSınavda sorulur
  • Değişken adının bir nesneye bağlanması
  • Nesnenin kimlik, tür ve değer özellikleri
  • Aynı nesneye iki referans olduğunda değişikliğin iki addan da görülmesi
  • is ile == ayrımı
  • Küçük tamsayı ve string önbelleklemesinden dil kuralı çıkarılamayacağı
  • Nesnenin durumu ve durumun hangi yollarla değiştiği
  • Yerinde değiştirme ile yeniden bağlama ayrımı
  • id() değerinin bellek adresiyle ilişkisi
  • Çöp toplama (garbage collection) ayrıntıları
  • CPython’ın hangi nesneleri yeniden kullandığının ayrıntıları

Bu başlıklar konunun devamıdır. İleride karşınıza çıkar, ama bu derste ezberlemeniz beklenmiyor.

Kırtasiyenin stok programındaki beş işi C’de nasıl yapardınız?

Bir kırtasiyenin stok programını yazıyorsunuz. Her ürünün bir adı ve depoda kaç tane kaldığını gösteren bir stok sayısı var. Program şu beş işi yapacak:

  1. Kalemin adını ve stok sayısını tek bir kayıtta tutmak
  2. Kasa ekranıyla depo ekranının aynı kaydı kullanması: kasada satılan kalem depo ekranında da eksilmeli
  3. Elinizdeki iki kaydın aynı kayıt mı, yoksa aynı bilgileri taşıyan iki ayrı kayıt mı olduğunu anlamak
  4. Satış fonksiyonu yazmak: fonksiyon, onu çağıran koddaki kaydın stoğunu azaltmalı
  5. Stoğun hiçbir zaman eksiye düşmemesini sağlamak

Programlama Temelleri’nde C ile yazdığınız programları düşünün. Bu işlerin her birini C’de nasıl yapardınız? Okumaya devam etmeden önce her iş için bir satır yazın. 3. haftadan beri bildiğiniz Python’la da cevap verebilirsiniz: “struct tanımlarım” da “sözlükte tutarım” da bir cevap.

Bölümde bu beş işin Python’da nasıl yürüdüğünü göreceğiz. Bölümün sonunda listenize döneceğiz.

Ad bir nesneye bağlanır

C’de struct Product pencil = {"Kalem", 10}; yazdığınızda pencil bellekte iki alanı olan bir kutuydu. pencil.stock = 8; o kutunun içindeki alanı değiştirirdi. Python’da aynı kaydı 3. haftada gördüğünüz sözlükle tutabilirsiniz:

product = {"name": "Kalem", "stock": 10}

Bu satır önce bir sözlük nesnesi oluşturur, sonra product adını o nesneye bağlar. Kutu benzetmesi tek bir adla çalışırken işe yarar, ama iki ad aynı nesneyi gösterdiği anda yetmez. Bu derste şu modeli kullanacağız:

Değişken adı, bir nesneye bağlanır.

Model sayılar için de geçerli. 3. haftada gördüğünüz id(), bir nesnenin kimlik numarasını döndürüyordu. Hücrede score adına iki kez değer atanıyor ve her atamadan sonra id(score) yazdırılıyor. C’deki kutu modeli doğru olsaydı iki sayı aynı çıkardı. Python’da aynı mı çıkar?

score = 90 satırı 80 nesnesinin içini 90 yapmaz. score adını, değeri 90 olan başka bir nesneye bağlar. Buna yeniden bağlama denir.

İki farklı sayı. Sayıların kendisi her çalıştırmada değişebilir, önemli olan birbirinden farklı olmaları: score adı önce bir nesneyi, sonra başka bir nesneyi gösterdi.

Her nesnenin kimliği, türü ve değeri var

Python’ın resmî belgelerindeki veri modeline (data model) göre her nesnenin bir kimliği (identity), bir türü (type) ve bir değeri (value) vardır. Kimlik nesneyi ötekilerden ayırır ve nesne var olduğu sürece değişmez. Tür, nesneyle hangi işlemleri yapabileceğinizi ve değerinin değişip değişemeyeceğini belirler. Değer nesnenin içeriğidir.

Python veri modelinde bir nesnenin kimlik, tür ve değer özelliklerini; OOP bağlamında değişebilen değerlerin durum olarak yorumlanmasını gösteren diyagram.

Nesnenin kimlik, tür ve değeri

Hücre kalem kaydının üç özelliğini yazdırıyor. Hangi satır kimliği, hangisi türü gösterir?

type(product) türü, id(product) kimliği, product ise değeri gösterir.

Noteid() değerini bellek adresi diye ezberlemeyin

Python kodunu çalıştıran programa Python uygulaması denir. Bilgisayarınıza kurduğunuz CPython ve bu sayfadaki Pyodide birer uygulamadır. Bazı uygulamalarda id() ile bellek adresi arasında yakın bir ilişki olabilir, ama dil bunu garanti etmez. Biz id() değerini yalnız iki adın aynı nesneyi gösterip göstermediğini görmek için kullanacağız. Bu iş için is daha okunaklıdır.

İki ad, tek kayıt

C’de struct ataması alanları kopyalar: struct Product selected = pencil; satırından sonra iki ayrı kayıt olur. Kasa ekranıyla depo ekranının aynı kaydı kullanması için işaretçi gerekirdi: struct Product *selected = &pencil;.

  1. haftada Python’da = işaretinin kopya almadığını, var olan nesneye bir ad daha bağladığını gördünüz. Buna aynı nesneye referans verme (aliasing) dedik. Sözlük de listeyle aynı davranır. Hücrede kasa ekranı selected adıyla iki kalem satıyor. print(product) ne yazar?

selected = product yeni bir sözlük oluşturmaz. product ve selected aynı sözlüğün iki adıdır, bu yüzden selected ile yapılan değişikliği product ile bakınca da görürüz. C’de işaretçinin yaptığı işi Python’da düz bir atama yapar.

ImportantKendi yazdığınız nesneler de kopyalanmaz

Gelecek hafta account, customer, order gibi adlar kendi yazdığınız sınıflardan oluşturulan nesneleri gösterecek. other = account satırı da hesabın kopyasını almaz, aynı hesaba bir ad daha bağlar. Hesap bir addan değiştirilirse öteki ad da yeni durumu görür.

Aynı kayıt mı, eşit kayıt mı?

C’de iki işaretçinin aynı kaydı gösterip göstermediğini işaretçileri == ile karşılaştırarak, iki kaydın aynı bilgileri taşıyıp taşımadığını ise alanları tek tek karşılaştırarak anlardınız. Python’da bu iki soru için iki ayrı işleç var. 3. haftada gördüğünüz gibi is iki adın aynı nesneyi gösterip göstermediğini, == iki değerin eşit olup olmadığını sorar.

Hücrede second, first sözlüğünün .copy() ile alınmış kopyası (3. haftada gördüğümüz, yeni bir nesne oluşturan kopya). third ise first ile atanıyor. Üç satır ne yazar?

İçeriği eşit iki nesne, iki ayrı kayıt olabilir. Aynı kaydı gösteren iki adı yalnız is ayırt eder.

  • first == second → True: iki sözlüğün anahtarları ve değerleri eşit.
  • first is second → False: .copy() yeni bir sözlük oluşturdu.
  • first is third → True: third = first aynı sözlüğe bir ad daha bağladı.

is işlecinin nesne kimliğini, çift eşittirin ise değer eşitliğini sorguladığını gösteren diyagram.

Kimlik ve eşitlik

Küçük sayılarda is neden bazen True verir?

Hücrede aynı değerdeki sayılar iki kez karşılaştırılıyor: önce 5 ile 5, sonra metinden dönüştürülen iki 1000. Üç satır ne yazar?

Python uygulaması küçük tamsayılar ve bazı stringler için her seferinde yeni nesne oluşturmaz, var olanı yeniden kullanır. Buna önbellekleme (caching) denir, stringlerde interning adı da kullanılır. Uygulama bunu hız ve bellek kazanmak için yapar. “Aynı değerdeki sayılar aynı nesnedir” diye bir dil kuralı yoktur: CPython, Pyodide ya da başka bir uygulama hangi nesneleri yeniden kullanacağına kendisi karar verir.

ImportantSayıları ve metinleri == ile karşılaştırın

Bir is deneyinde True görmeniz, başka bir sayıda ya da başka bir uygulamada da True göreceğiniz anlamına gelmez. Değer sorusunu == ile sorun. is en sık value is None biçiminde, bir değerin None olup olmadığını denetlemek için kullanılır. Programda tek bir None nesnesi olduğu için bu soru kimlikle sorulur.

Fonksiyon kaydın kopyasını değil kendisini alır

C’de bir struct’ı fonksiyona verdiğinizde fonksiyon onun kopyasını alırdı. Satışın çağıran koddaki kayda yansıması için işaretçi verirdiniz: sell(&pencil, 2). 4. haftada Python’da parametre adının, çağıranın verdiği nesneye bağlandığını gördünüz.

Hücredeki sell fonksiyonu sözlüğü işaretçi olmadan alıyor. Fonksiyonun içindeki ad product, dışarıdaki ad pencil. Son satır ne yazar?

Çağrıda product parametresi pencil sözlüğüne bağlanır, Python sözlüğü kopyalamaz. Fonksiyonun sözlükte yaptığı değişikliği çağıran kod da görür.

Parametreye yeni değer atamak çağıranı etkilemez

C’de void increase(int n) fonksiyonu çağıranın değişkenini değiştiremezdi. Python’da aşağıdaki fonksiyon parametresine yeni bir değer atıyor ve içeride 11 yazdırıyor. Son satır ne yazar?

number = number + 1 satırı yeni bir int nesnesi oluşturur ve yalnız fonksiyonun yerel number adını ona bağlar. value adı hâlâ eski nesneyi gösterir.

İki fonksiyonun farklı davranmasının nedeni sayı ile sözlüğün türü değil, fonksiyonun içinde yapılan iştir. sell sözlüğü yerinde değiştirdi: aynı nesnenin içeriği değişti. increase ise adı yeniden bağladı: yerel ad başka bir nesneyi göstermeye başladı. sell içinde product = {"name": "Silgi", "stock": 0} yazsaydık bu da yalnız yerel adı yeniden bağlardı ve pencil değişmezdi.

Nesnenin durumu

OOP’de bir nesnenin o anki verilerine, özellikle de nesnenin nasıl davranacağını etkileyenlere, onun durumu (state) deriz. Değiştirilebilir (mutable) bir nesnenin durumu program çalışırken değişebilir.

{"name": "Kalem", "stock": 8} sözlüğünde stock değeri durumun bir parçasıdır. Stok 8’den 7’ye inerse nesnenin durumu değişir, kimliği ve türü aynı kalır. Stok 0 olunca satış yapılamaz: durum, nesneyle neyin yapılabileceğini belirler.

Note“Değer” Python’ın, “durum” tasarımın terimi

Değer (value) Python veri modelinin her nesne için kullandığı terimdir: [70, 80] listesinin değeri içindeki iki sayıdır. Durum (state) ise OOP’de nesneyi tasarlarken kullandığımız terimdir: nesnenin o anki verilerinden davranışını etkileyenler. Bir banka hesabının bakiyesi onun durumudur, bakiye yetmezse para çekilemez. Mutable bir nesnenin değeri değiştiğinde çoğu zaman “nesnenin durumu değişti” deriz. İki terim birbirine yakındır, ama ikisini birbirinin yerine kullanmayacağız.

OOP’de sık sık şu soruyu soracağız:

Bu durumun hangi yollarla değişmesine izin veriyoruz?

Stok örneğinde: stock değerini yalnız satış yapan fonksiyon mu değiştirebilmeli, yoksa programın her yerinden product["stock"] = -100 yazılabilmeli mi?

Davranış neden verinin yanında olmalı?

Az önceki sell fonksiyonuyla, stokta iki kalem varken beş kalem satalım. Son satır ne yazar?

Program hata vermeden çalışır. “Stok eksiye düşemez” kuralını denetleyen tek bir satır bile yok.

  1. haftada gördüğümüz raise ile fonksiyona bir denetim ekleyelim. Hücre ne yazar? Satış reddedilirse stok değişir mi?

Denetim, stoğu değiştiren satırdan önce çalışır. Satış reddedilince stok olduğu gibi kalır.

Bu küçük örnekte kural sell fonksiyonunun içinde duruyor. Ama program büyüdükçe product sözlüğünde hangi anahtarların bulunması gerektiğini ve sözlüğü hangi fonksiyonların değiştirdiğini izlemek zorlaşır. Başka bir dosyadaki bir fonksiyon product["stock"] değerini hiç denetlemeden değiştirebilir. C’de bir struct ile onu değiştiren fonksiyonlar da böyle ayrı ayrı dururdu.

OOP’de nesnenin verisine durum, bu veriyle yapılan işlere, yani veriyi okuyan ve değiştiren fonksiyonlara davranış denir. Gelecek hafta göreceğimiz sınıf (class), durumu ve davranışı tek bir ad altında, aynı yapıda toplar.

Soruya dönelim: stok programının beş işi

Bölümün başında kırtasiyenin stok programındaki beş işi C’de nasıl yapacağınızı sormuştuk. Python’daki karşılıkları şöyle:

İş C’de ya da önceki haftalarda Bu haftaki Python yolu Dikkat
Kaydı tutmak struct Product pencil = {"Kalem", 10}; product = {"name": "Kalem", "stock": 10}: product adı bir sözlük nesnesine bağlanır Yeni atama nesneyi değiştirmez, adı başka bir nesneye bağlar
Kasa ve depo aynı kaydı kullanır İşaretçi: struct Product *selected = &pencil; selected = product = hiçbir türde kopya almaz. Ayrı bir kayıt için .copy() gerekir
Aynı kayıt mı, eşit mi? İşaretçileri == ile, alanları tek tek karşılaştırmak is kimliği, == değeri sorar Sayıları ve metinleri is ile karşılaştırmayın
Satış fonksiyonu Fonksiyona işaretçi vermek: sell(&pencil, 2) sell(product, 2): parametre aynı sözlüğe bağlanır Parametreye yeni değer atamak çağıranın adını değiştirmez
Stok eksiye düşmesin sell içinde if ile denetlemek sell içinde raise ValueError Kodun başka bir yeri yine product["stock"] = -100 yazabilir

Listenizi tabloyla karşılaştırın. 2. iş için “selected = product yazarım” dediyseniz Python’da doğru cevabı vermişsiniz, ama C’de aynı satır iki ayrı kayıt oluştururdu: C’de struct ataması kopyalar, Python’da = paylaşır. 4. işte C’de işaretçi gerekirdi. Python’da gerekmez, çünkü parametre zaten verilen nesneye bağlanır. 5. iş iki dilde de yarım kalıyor: kural sell içinde, ama kayıt programın her yerinden değiştirilebilir. Gelecek hafta veriyi ve onu değiştiren fonksiyonları bir sınıfta toplayacağız. 8. haftada da kuralı sınıfın içinde koruyacağız.

Alıştırma: Aynı mı, eşit mi?

Hücre dört satır yazdırıyor. Önce dört satırı tahmin edin, sonra çalıştırın.

Ardından koda c.append(3) satırını ekleyin ve a, b, c değerlerini yeniden yazdırın. Hangi adların değiştiğini açıklayın.

Alıştırma: Referans diyagramı

first = {"balance": 100}
second = first
third = {"balance": 100}

Üç değişken adını ve kaç ayrı sözlük nesnesi olduğunu gösteren bir diyagram çizin. Ardından second["balance"] += 50 satırından sonra hangi adlarla bakınca 150 görüleceğini açıklayın.

Alıştırma: Geçersiz durumu engelle

if amount > account["balance"]:
    raise ValueError("Yetersiz bakiye")

Sıra sizde: Prosedürel hesabı incele

account = {
    "owner": "Ada",
    "balance": 500,
}

Veriyi bir sözlükte, işlemleri ayrı fonksiyonlarda tutan bu yaklaşıma prosedürel yaklaşım denir. C’de bir struct ve onu işleyen ayrı fonksiyonlarla çalışmak da aynı yaklaşımdır. Para yatırma, para çekme ve bakiye sorgulama fonksiyonlarını yazın. Geçersiz tutarlarda ValueError yükseltin ve başarısız bir işlemden sonra sözlüğün değişmediğini doğrulayın.

Çalışır kod görevi: Üç durumu deneyin: normal para çekme, yetersiz bakiye ve negatif tutar. Bakiyeyi en az üç assert ile denetleyin. 5. haftadaki gibi assert satırı, koşul yanlışsa AssertionError yükseltir: assert account["balance"] == 400.

Sonunda şu soruyu cevaplayın:

Bu üç fonksiyonu ve hesabın verisini tek bir yapıda toplarsak ne kazanırız?

Bu sorunun cevabı bizi gelecek hafta class BankAccount tasarımına götürecek.

Sınav provası

Önce kendi cevabınızı seçin; sonra cevap anahtarında her şıkkın neden doğru veya yanlış olduğunu okuyun. Çeldiriciler uydurma değil, bu konuda gerçekten yapılan hatalardır. Sınav maddeleri de bu mantıkla yazılır.

Madde 1. score = 80 ve ardından score = 90 yazıldığında ne olur?

  • A. score adlı kutunun içindeki 80 değeri 90 ile üzerine yazılır
  • B. İki ayrı score değişkeni oluşur
  • C. Hata verir; bir ada iki kez atama yapılamaz
  • D. score adı başka bir nesneye yeniden bağlanır
  • E. 80 değeri bellekten hemen silinir ve score geçersiz olur

Madde 2. Python veri modelinde her nesnenin sahip olduğu üç özellik nedir?

  • A. Durum, davranış ve sorumluluk
  • B. Sınıf, metot ve nitelik
  • C. Değer, kopya ve referans
  • D. Ad, adres ve boyut
  • E. Kimlik, tür ve değer

Madde 3. Bu derste “değer” ile “durum” terimleri nasıl ayrılır?

  • A. “Durum” nesnenin kimliğidir
  • B. İkisi eş anlamlıdır; yalnız farklı kitaplarda farklı yazılır
  • C. “Değer” veri modelinin, “durum” nesne tasarımının terimidir
  • D. “Değer” çalışma anında, “durum” derleme anında belirlenir
  • E. “Değer” yalnızca sayılar, “durum” yalnızca nesneler için kullanılır

Madde 4. Aşağıdaki program ne yazdırır?

product = {"name": "Kalem", "stock": 10}
selected = product
selected["stock"] -= 2

print(product["stock"])
print(product is selected)
  • A. 8 ve True
  • B. Hata verir; sözlük değeri -= ile güncellenemez
  • C. 10 ve False
  • D. 8 ve False
  • E. 10 ve True

Madde 5. Aşağıdaki program ne yazdırır?

first = {"name": "Kalem"}
second = {"name": "Kalem"}
third = first

print(first == second)
print(first is second)
print(first is third)
  • A. True, False, False
  • B. True, False, True
  • C. False, False, True
  • D. False, True, True
  • E. True, True, True

Madde 6. is operatörünün önerilen tipik kullanımı hangisidir?

  • A. liste is [] biçiminde boşluk kontrolü
  • B. type(x) is int yerine her yerde x is int
  • C. value is None biçimindeki kimlik kontrolü
  • D. score is 100 biçiminde sayı karşılaştırması
  • E. name is "Ada" biçiminde metin karşılaştırması

Madde 7. a = 5 ve b = 5 iken a is b bazı ortamlarda True verir. Bundan hangi sonuç çıkarılabilir?

  • A. Pyodide Python’ın standart davranışını bozmaktadır
  • B. Bu bir uygulama tercihidir, dil kuralı değildir
  • C. is operatörü sayılarda == ile aynı işi yapar
  • D. Küçük sayılarda == kullanmak hatalıdır
  • E. Python’da aynı değerdeki sayılar her zaman aynı nesnedir

Madde 8. Aşağıdaki program neden sorunludur?

product = {"name": "Kalem", "stock": 2}

def sell(product, amount):
    product["stock"] -= amount

sell(product, 5)
print(product)
  • A. Stok -3 olur; eksiye düşmeyi engelleyen denetim yok
  • B. amount parametresi product ile aynı adı taşıdığı için çakışma olur
  • C. Sorun yoktur; negatif stok geçerli bir durumdur
  • D. sell fonksiyonu sözlüğü değiştiremez; değişiklik kaybolur
  • E. KeyError yükselir

Madde 9. Sözlükte tutulan bir kaydı sınıfa taşımanın temel gerekçesi nedir?

  • A. Sınıflar veriyi değiştirilemez yaptığı için
  • B. Sınıflar sözlüklerden daha hızlı çalıştığı için
  • C. Sözlükler fonksiyonlara parametre olarak verilemediği için
  • D. Veri ve onu değiştiren metotlar aynı yapıda durur
  • E. Sözlükler yalnızca metin anahtar kabul ettiği için

Madde 10. Aşağıdaki iki program neden farklı davranır?

# A
def add_tag(tags):
    tags.add("oop")

labels = {"python"}
add_tag(labels)
print(labels)

# B
def increase(number):
    number = number + 1

value = 10
increase(value)
print(value)
  • A. A’da küme, B’de sayı kullanıldığı için Python birinde referans, diğerinde değer geçirir
  • B. İkisi de aynı davranır; 10 ve {'python'} yazdırır
  • C. A’da global bir değişken kullanıldığı için
  • D. B’de fonksiyon return içermediği için değişiklik kaybolur
  • E. A’da küme yerinde değişir; B’de yalnız yerel number adı yeniden bağlanır

Madde 1. Doğru: D. Atama bir kutunun içeriğini değiştirmez; adın hangi nesneyi gösterdiğini değiştirir. İlk nesnenin içi değiştirilmez.

  • A yanlış: C’deki int score; bir bellek kutusu gibi çalıştığı için bu model akla yatkındır. Ama kutu modeli burada yanıltır; int nesneleri değiştirilemez ve içleri güncellenmez.
  • B yanlış: İki atama iki ayrı nesneyle çalıştığı için iki değişken varmış gibi görünür. Oysa tek bir ad vardır; yalnız bağlandığı nesne değişir.
  • C yanlış: Bir adın bir kez bağlandıktan sonra sabit kaldığı düşünülebilir. Oysa yeniden atama geçerli ve olağandır.
  • E yanlış: Eski değerin artık kullanılmaması, onun hemen silindiği izlenimini verir. Ama ad her zaman geçerli bir nesneyi gösterir; eski nesneye ne olacağı ise ayrı bir konudur.

Madde 2. Doğru: E. Tür, nesneyle yapılabilecek işlemleri ve değerin değişip değişemeyeceğini belirler; kimlik nesneyi ötekilerden ayırır.

  • A yanlış: Bunlar OOP tasarım terimleridir; veri modelinin üç özelliği değildir.
  • B yanlış: Bunlar sınıf yazarken kullanılan kavramlardır; veri modelinin her nesne için saydığı özellikler değildir.
  • C yanlış: Kopya ve referans işlem biçimleridir; nesnenin özellikleri değildir.
  • D yanlış: Ad nesnenin parçası değildir, yalnızca nesneye bağlanır; dil de adres ve boyutu her nesnenin özelliği olarak tanımlamaz.

Madde 3. Doğru: C. “Değer” Python veri modelinin genel terimidir. “Durum” ise OOP’de nesnenin o anki verilerinden davranışını etkileyenleri anlatan tasarım terimidir. Mutable bir nesnenin değeri değişince çoğu zaman “durumu değişti” deriz; iki terim ilişkilidir ama birbirine karıştırılmamalıdır.

  • A yanlış: Durum da kimlik de nesneyi tanıtan özellikler olduğu için karıştırılabilir. Ama kimlik nesne yaşadığı sürece sabittir; durum değişebilir.
  • B yanlış: Günlük dilde iki sözcük birbirinin yerine kullanıldığı için eş anlamlı sanılabilir. Ama “değer” Python dil başvurusunun, “durum” nesne tasarımının terimidir.
  • D yanlış: C’deki derleme anı ile çalışma anı ayrımı bu eşleştirmeyi akla getirir. Python’da böyle bir derleme anı ayrımı yoktur.
  • E yanlış: Örneklerde “değer” çoğunlukla sayılar için geçtiğinden böyle bir ayrım sanılabilir. Oysa iki terim de her türden nesne için kullanılır.

Madde 4. Doğru: A. selected = product yeni bir sözlük oluşturmaz; aynı sözlüğün iki adı olur. Birinden yapılan değişiklik ötekinden de görülür.

  • B yanlış: Bu yazım selected["stock"] = selected["stock"] - 2 ile aynıdır ve geçerlidir.
  • C yanlış: Atama kopya oluşturmaz; iki ad aynı nesneyi gösterir.
  • D yanlış: is aynı nesne için True verir.
  • E yanlış: Aynı nesne değiştirildiği için product da yeni değeri gösterir.

Madde 5. Doğru: B. first ve second eşit içerikli ama ayrı nesnelerdir. third ise first ile aynı nesnedir.

  • A yanlış: third = first aynı nesneye ikinci bir ad bağlar.
  • C yanlış: Sözlüklerde == anahtarları ve değerleri karşılaştırır; ikisi de aynı olduğu için sonuç True olur.
  • D yanlış: İlk iki sonuç ters yazılmış.
  • E yanlış: Eşit içerik aynı nesne olmayı gerektirmez.

Madde 6. Doğru: C. Programda tek bir None nesnesi vardır; bu yüzden bir değerin None olup olmadığı kimlikle sorulur.

  • A yanlış: Her [] yeni bir liste oluşturur; bu karşılaştırma hep False verir.
  • B yanlış: x is int, x değerini int türünün kendisiyle karşılaştırır; bu anlamsızdır.
  • D yanlış: Sayı eşitliği için == kullanılır.
  • E yanlış: Metin eşitliği için == kullanılır; is sonucu uygulama ayrıntısına bağlı olabilir.

Madde 7. Doğru: B. Uygulama küçük tamsayıları yeniden kullanır. Bu önbellekleme davranışı CPython, Pyodide ya da başka bir uygulamada farklı görünebilir. Değer sorusu için == kullanılmalıdır.

  • A yanlış: Ortamlar arasında farklı sonuç görmek, birinin hatalı olduğu izlenimini verir. Dil önbelleklemeyi zorunlu tutmaz; uygulamaların farklı davranması bir bozulma sayılmaz.
  • C yanlış: İki operatör burada aynı sonucu verdiği için aynı işi yapıyormuş gibi görünür. Ama farklı sorulardır; sonuçların rastlantısal olarak örtüşmesi bunu değiştirmez.
  • D yanlış: is daha kesin bir karşılaştırma gibi göründüğü için tercih edilesi sanılabilir. Tersine, değer karşılaştırmasında güvenilir olan ==dır.
  • E yanlış: Deneyde True görüldüğü için sonucu her sayıya genellemek kolaydır. Ama int("1000") ile oluşturulan iki değer aynı nesne olmayabilir.

Madde 8. Doğru: A. Program hata vermeden çalışır. Eksik olan, stoğun eksiye düşmesini engelleyen bir denetimdir.

  • B yanlış: Adlar farklıdır ve çakışma yoktur.
  • C yanlış: Stok eksiye düşemez; bu durumun hata vermeden kabul edilmesi asıl sorundur.
  • D yanlış: Fonksiyon aynı sözlük nesnesini değiştirir; değişiklik çağıran taraftan da görülür.
  • E yanlış: stock anahtarı mevcuttur.

Madde 9. Doğru: D. Program büyüdükçe sözlükte hangi anahtarların bulunması gerektiğini ve kaydı hangi fonksiyonların değiştirebildiğini izlemek zorlaşır. Sınıf, veriyi ve onu değiştiren fonksiyonları aynı yerde toplar.

  • A yanlış: Sınıftan oluşturulan nesnelerin verisi de değişebilir; sınıfla korunan şey, verinin uyması gereken kurallardır.
  • B yanlış: Gerekçe hız değil, verinin ve onu değiştiren kodun bir arada durmasıdır.
  • C yanlış: Verilebilir; bu bölümdeki sell(product, 5) çağrısı bunu yapıyor.
  • E yanlış: Sözlükler hashlenebilir her türü anahtar olarak kabul eder.

Madde 10. Doğru: E. Yerinde değiştirme paylaşılan nesneyi etkiler. B’de parametre adı yeni bir nesneye bağlanır; bu yalnız fonksiyonun kendi adını etkiler, çağıran taraftaki value değişmez. A {'python', 'oop'}, B 10 yazdırır.

  • A yanlış: C’deki değerle ve işaretçiyle geçirme ayrımı bu açıklamayı akla yatkın kılar. Ama iki çağrıda da argüman aynı biçimde aktarılır; fark fonksiyonun içinde yapılan işlemdedir.
  • B yanlış: B’nin davranışını A’ya da genellemek kolaydır. Ama A’daki add çağrısı kümeyi gerçekten değiştirir.
  • C yanlış: labels fonksiyonun dışında tanımlandığı için global gibi görünebilir. Ama labels parametreyle geçirilir; global bildirimi yoktur.
  • D yanlış: Sonucun dışarı çıkması için return gerektiği bilgisi burada yanlış yere uygulanır. return olsa bile dönen değer value adına atanmadıkça çağıranın adı değişmezdi; farkın nedeni yeniden bağlamadır.

Tek sayfa özet

  • Python’da her değer bir nesnedir. Değişken adı nesne değildir, bir nesneye bağlanır.
  • Yeni atama nesnenin içini değiştirmez, adı başka bir nesneye bağlar. Buna yeniden bağlama denir.
  • Python veri modelinde her nesnenin kimliği, türü ve değeri vardır.
  • b = a kopya almaz. İki ad aynı nesneyi gösterir ve bir addan yapılan değişikliği öteki de görür. C’de işaretçinin yaptığı işi Python’da düz atama yapar.
  • == eşitlik, is kimlik sorusudur. Eşit içerikli iki nesne iki ayrı nesne olabilir.
  • Küçük tamsayı ve string önbelleklemesi uygulamanın tercihidir. Değer karşılaştırmasını == ile yapın, is’i None denetimi gibi kimlik soruları için kullanın.
  • Fonksiyon çağrılınca parametre adı verilen nesneye bağlanır. Fonksiyon nesneyi yerinde değiştirirse çağıran da görür, parametreyi yeniden bağlarsa çağıranın adı değişmez.
  • OOP’de nesnenin davranışını etkileyen, zamanla değişen verilerine durum deriz.
  • Sözlükteki veriyi programın her yeri değiştirebilir. Veriyi ve onu kurallara uyarak değiştiren fonksiyonları tek bir yapıda, sınıfta toplamamızın bir nedeni bu.

Bu bölümün kazanımları

Bu bölümü bitiren öğrenci:

  • Değişken adının bir nesneye bağlandığını, kutu olmadığını açıklar.
  • Bir nesnenin kimlik, tür ve değer özelliklerini ayırt eder.
  • Aynı nesneye iki referans olduğunda bir addan yapılan değişikliğin diğerinden görüldüğünü gösterir.
  • is ile == sorularını ayırt eder ve is işlecini yalnızca kimlik sorusu için kullanır.
  • Küçük tamsayı ve string önbelleklemesinden dil kuralı çıkarılamayacağını açıklar.
  • Nesnenin durumunu tanımlar ve durumun hangi yollarla değişebileceğini sorgular.
  • Mutable nesnede yerinde değişiklik ile immutable nesnede yeniden bağlamayı ayırt eder.
Back to top