Özel metotlar ve özel istisnalar
Python’daki nesneler yalnızca bizim yazdığımız normal metotlarla değil, dilin veri modeliyle de etkileşir. print(obj), obj1 == obj2 veya hata ayıklayıcıda nesnenin görünümü gibi davranışlar özel metotlarla tanımlanabilir. Bu hafta ayrıca problem alanına özgü hataları kendi istisna sınıflarımızla ifade edeceğiz.

__str__, __eq__ ve özel istisnanın bir ürün sınıfında kullanıcıya görünen temsil, eşitlik ve alan hatası davranışlarını tanımlaması.Bu hafta neleri yapabilmelisiniz?
__str__ve__repr__amaçlarını ayırabilmeli,__eq__ile değer eşitliği tanımlayabilmeli,- kimlik ile eşitlik ayrımını yeniden uygulayabilmeli,
- eşitlik tanımının hash edilebilirlik üzerinde etkisi olabileceğini tanıyabilmeli,
- özel istisna sınıfı tanımlayabilmeli,
- alan kuralı ihlalini anlamlı istisnayla ifade edebilmeli,
- istisnayı uygun katmanda yakalama fikrini açıklayabilmelisiniz.
Varsayılan nesne temsili
Varsayılan çıktı genellikle sınıf adı ve nesneyi ayırt etmeye yarayan uygulama ayrıntıları içerir. Kullanıcı veya geliştirici için çoğu zaman yeterince anlamlı değildir.
__str__: okunabilir kullanıcı temsili
print(product) artık __str__() sonucunu kullanır.
__repr__: geliştiriciye dönük temsil
İdeal repr çoğu zaman nesnenin durumunu açıkça görmeye yardımcı olur. Her durumda yeniden çalıştırılabilir Python ifadesi üretmek zorunlu değildir; bu derste öncelik hata ayıklamada açık temsildir.
__eq__: iki nesne ne zaman eşit?
Varsayılan olarak kendi sınıfımızdaki iki ayrı örnek aynı alanlara sahip olsa bile == beklediğimiz alan anlamında çalışmayabilir:
Eşitliği ürün koduna göre tanımlamak istersek:
== artık alan kuralımıza göre eşitlik sorar; is hâlâ nesne kimliğini sorar.
Bir Product için yalnızca code mu önemlidir? Bir Book için ISBN mi? Bir Student için öğrenci numarası mı? __eq__ yazmadan önce problem alanında “aynı kabul edilme” kuralını belirleyin.
__eq__ ve hash sözleşmesi
Eşitlik tanımı, nesnenin set içinde veya dict anahtarı olarak kullanılmasıyla ilişkilidir. Python veri modelinde eşit kabul edilen nesnelerin aynı hash değerine sahip olması gerekir. Bir sınıf __eq__ tanımlayıp uygun bir __hash__ tanımlamazsa örnekleri varsayılan olarak hash edilemez hâle gelir.
Bu derste __hash__ yazmıyoruz. Özellikle durumu değişebilen alan nesnelerini set elemanı veya dict anahtarı yapmadan önce eşitlik ve hash tasarımını ayrıca düşünmek gerektiğini bilmeniz yeterlidir.
Alan hatalarını özel istisnayla ifade etmek
Yerleşik ValueError birçok durumda yeterlidir. Ancak belirli bir iş kuralını çağıranın ayırt etmesi gerekiyorsa özel istisna anlamlı olabilir.
Aşağıdaki örnekte önce genel giriş kurallarını ValueError ile, alanın özel başarısızlık durumunu ise ayrı bir istisna sınıfıyla ifade ediyoruz:
Bu sürümde başarısız para çekme işlemi hesabın geçerli durumunu bozmaz. Negatif tutarın bakiyeyi yanlışlıkla artırmasına da izin verilmez.
İstisnayı nerede yakalamalı?
Nesne metodu çoğu zaman hatayı üretir, kullanıcı arayüzü veya uygulama katmanı hatayı yakalar.
# domain.py
account.withdraw(amount) # hata üretebilir
# app.py
try:
account.withdraw(amount)
except InsufficientBalanceError as error:
print(error)Account.withdraw() hatayı kendi içinde yakalayıp yalnızca print() ederse çağıran kod işlemin başarısız olduğunu güvenilir biçimde ayırt edemez.
Alıştırma — __str__ ekle
Beklenen çıktı:
2026001 — Ada
return f"{self.student_id} — {self.name}"Alıştırma — Eşitlik kuralını seç
Bir Book sınıfında şu alanlar var:
isbntitleauthor
İki kitabın eşit sayılması için hangi alanı kullanmak daha mantıklı? Cevabınıza göre __eq__ yazın. Başka türden nesne geldiğinde NotImplemented döndürün.
Bu alıştırmada __hash__ yazmanız beklenmez. Oluşturduğunuz nesneleri set elemanı veya dict anahtarı olarak kullanmaya çalışmadan önce yukarıdaki hash notunu hatırlayın.
Alıştırma — Özel istisna
Aşağıdaki sınıfta iki farklı hata türünü ayırın: geçersiz miktar için ValueError, yetersiz stok için OutOfStockError.
Product(2).sell(5) çağrısını try/except ile yakalayın ve stok değerinin değişmediğini doğrulayın. Ardından sell(-1) çağrısının stoku artırmadığını ve ValueError ürettiğini kontrol edin.
Küçük üretim görevi — Üyelik modeli
Member sınıfı oluşturun:
member_idnameactive
__str__ okunabilir kısa temsil, __repr__ geliştirici temsili, __eq__ ise member_id eşitliği kullansın.
Ayrıca InactiveMemberError özel istisnasını tanımlayın. ensure_active() metodu pasif üyede bu hatayı üretsin.
Son olarak iki farklı ama aynı member_id değerine sahip nesnede == ile is sonuçlarını karşılaştırın.
Kendinizi kontrol edin
__str__ile__repr__hangi farklı hedeflere yönelir?__eq__neden problem alanı kararıdır?==tanımlansa bileisneden değişmez?__eq__tanımlamak nedenset/dictkullanımı açısından ayrıca düşünülmelidir?- Özel istisna ne zaman
ValueError’dan daha anlamlı olabilir? - Neden geçersiz miktarı durum değişikliğinden önce kontrol etmek gerekir?
- Alan nesnesi istisnayı neden çoğu zaman kendi içinde yutmamalıdır?
Bu haftadan akılda kalması gerekenler
- Özel metotlar sınıfımızı Python’ın veri modeliyle uyumlu hâle getirir.
__str__okunabilir,__repr__geliştirici odaklı temsildir.__eq__eşitliğin alan anlamını kodlar; hash edilebilirlik ayrı ama ilişkili bir sözleşmedir.iskimlik sorusu olmaya devam eder.- Özel istisnalar, belirli iş kurallarını açık hata türleriyle ifade edebilir.
- İstisna üretmeden önce geçersiz durumları doğrulamak, nesnenin invariant’ını korumaya yardımcı olur.