Kapsayıcı Sihirli Metotları
Coddy'nin Python Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 35 / 64.
Konteyner sihirli metotları, sınıflarınızın yerleşik konteynerler (listeler, sözlükler vb.) gibi davranmasını sağlar. Özel nesneleriniz üzerinde indeksleme, uzunluk kontrolü ve yineleme yapılmasına olanak tanırlar.
İşte kapsayıcı sihirli metotlara sahip bir sınıf örneği:
class CustomList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
def __getitem__(self, index):
return self.items[index]
def __setitem__(self, index, value):
self.items[index] = value
def __iter__(self):
return iter(self.items)
def __contains__(self, item):
return item in self.items__len__ metodu len() fonksiyonunun çalışmasını sağlar:
my_list = CustomList([1, 2, 3, 4])
print(len(my_list)) # 4__getitem__ metodu, veri çekmek için indekslemeyi etkinleştirir:
print(my_list[2]) # 3
print(my_list[0]) # 1__setitem__ metodu, atama için indekslemeyi etkinleştirir:
my_list[1] = 10
print(my_list[1]) # 10__contains__ metodu, in operatörünün çalışmasını sağlar:
print(3 in my_list) # True
print(100 in my_list) # False__iter__ metodu yinelemeyi sağlar:
for item in my_list:
print(item)Çıktı:
4
3
1
10
True
False
1
10
3
4Anahtar Nokta: __len__, __getitem__, __setitem__, __iter__ ve __contains__ gibi kapsayıcı sihirli metotları, özel sınıflarınızın yerleşik kapsayıcılar gibi davranmasını sağlar. Bu, nesneleriniz için sezgisel indeksleme, yineleme ve üyelik testi sağlar.
Görev
OrtaBu meydan okumada, kapsamlı işlevselliğe ve uygun Python kurallarına sahip bir oyun kağıdı destesini simüle eden bir Deck sınıfı uygulayacaksınız.
Sadece deck.py dosyasını düzenlemeniz yeterlidir. Aşağıdakileri uygulamanızda size yol gösterecek olan kod içindeki TODO yorumlarını takip edin:
- Standart bir 52 kartlık deste başlatma ("2H", "KD", "AS" gibi dizeler kullanarak)
- Python'ın yerleşik işlemlerini destekleme:
- İndeksleme (
deck[0]) - Uzunluk kontrolü (
len(deck)) - Yineleme (
for card in deck) - Üyelik testi (
"AS" in deck)
- İndeksleme (
- Kart sırasını rastgele hale getirmek için bir
shuffleyöntemi
Kopya kağıdı
Konteyner sihirli metotları, sınıflarınızın yerleşik konteynerler (listeler, sözlükler vb.) gibi davranmasını sağlar. Özel nesneleriniz üzerinde indeksleme, uzunluk kontrolü ve yineleme yapılmasına olanak tanırlar.
Temel konteyner sihirli metotları:
__len__()-len()fonksiyonunu etkinleştirir__getitem__()- veri alma için indekslemeyi etkinleştirir__setitem__()- atama için indekslemeyi etkinleştirir__iter__()- yinelemeyi etkinleştirir__contains__()-inoperatörünü etkinleştirir
class CustomList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
def __getitem__(self, index):
return self.items[index]
def __setitem__(self, index, value):
self.items[index] = value
def __iter__(self):
return iter(self.items)
def __contains__(self, item):
return item in self.itemsKullanım örnekleri:
my_list = CustomList([1, 2, 3, 4])
# Uzunluk kontrolü
print(len(my_list)) # 4
# İndeksleme
print(my_list[2]) # 3
my_list[1] = 10
# Üyelik testi
print(3 in my_list) # True
# Yineleme
for item in my_list:
print(item)Kendin dene
from deck import Deck
# Kapsamlı test durumu işleyicisi
test_case = input()
def test_basic_functionality():
deck = Deck()
assert len(deck) == 52, f"Deck should have 52 cards, but has {len(deck)}"
first_card = deck[0]
assert isinstance(first_card, str), f"Card should be a string, but got {type(first_card)}"
assert "AS" in deck, "Ace of Spades should be in the deck"
assert "XY" not in deck, "XY is not a valid card and should not be in the deck"
cards = [card for card in deck]
assert len(cards) == 52, f"Iteration should yield 52 cards, but got {len(cards)}"
original_first_five = [deck[i] for i in range(5)]
deck.shuffle()
shuffled_first_five = [deck[i] for i in range(5)]
assert original_first_five != shuffled_first_five or len(deck) <= 5, "Shuffle should change card order"
print("Basic functionality tests passed!")
def test_edge_cases():
deck = Deck()
# İlk ve son kart erişimini test et
first_card = deck[0]
last_card = deck[51]
assert isinstance(first_card, str) and isinstance(last_card, str), "First and last cards should be strings"
# Negatif indekslemeyi test et
assert deck[-1] == deck[51], "Negative indexing should work correctly"
# Sınır dışı erişimi test et
try:
invalid_card = deck[52]
print("Test failed: Should raise IndexError for out of bounds access")
except IndexError:
print("Edge case test passed: IndexError raised for out of bounds access")
print("Edge case tests passed!")
def test_card_uniqueness():
deck = Deck()
cards = [card for card in deck]
unique_cards = set(cards)
assert len(unique_cards) == 52, f"All cards should be unique, but found {len(unique_cards)} unique cards"
# Belirli kartların varlığını doğrula
expected_cards = ["2H", "10S", "KD", "AC"]
for card in expected_cards:
assert card in deck, f"Expected card {card} not found in deck"
print("Card uniqueness tests passed!")
def test_shuffle_behavior():
deck = Deck()
original_order = [card for card in deck]
# İlk karıştırma
deck.shuffle()
first_shuffle = [card for card in deck]
assert len(first_shuffle) == 52, "Shuffle should preserve all 52 cards"
assert set(first_shuffle) == set(original_order), "Shuffle should not add or remove cards"
# Büyük olasılıkla sıra değişti (yine de değişmeme ihtimali çok düşüktür)
different_order = (original_order != first_shuffle)
# Emin olmak için ikinci karıştırma
deck.shuffle()
second_shuffle = [card for card in deck]
different_order_2 = (first_shuffle != second_shuffle)
assert different_order or different_order_2, "Multiple shuffles should change the order"
print("Shuffle behavior tests passed!")
def test_contains_behavior():
deck = Deck()
# Tüm geçerli kartların destede olduğunu test et
suits = ['H', 'D', 'C', 'S']
ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
for suit in suits:
for rank in ranks:
card = rank + suit
assert card in deck, f"Valid card {card} should be in the deck"
# Geçersiz kartların destede olmadığını test et
invalid_cards = ["1H", "11S", "XD", "AX", "JX", ""]
for card in invalid_cards:
assert card not in deck, f"Invalid card {card} should not be in the deck"
print("Contains behavior tests passed!")
def test_iteration_behavior():
deck = Deck()
# Yinelemeyi test et
card_count = 0
for card in deck:
card_count += 1
assert isinstance(card, str), f"Each card should be a string, but got {type(card)}"
assert card_count == 52, f"Iteration should yield 52 cards, but got {card_count}"
# Birden fazla yinelemeyi test et
first_iteration = [card for card in deck]
second_iteration = [card for card in deck]
assert first_iteration == second_iteration, "Multiple iterations should yield the same order"
print("Iteration behavior tests passed!")
# Girdiye göre uygun testi çalıştır
if test_case == "basic_functionality":
test_basic_functionality()
elif test_case == "edge_cases":
test_edge_cases()
elif test_case == "card_uniqueness":
test_card_uniqueness()
elif test_case == "shuffle_behavior":
test_shuffle_behavior()
elif test_case == "contains_behavior":
test_contains_behavior()
elif test_case == "iteration_behavior":
test_iteration_behavior()
else:
# Varsayılan test - orijinal test paketini çalıştır
def test_deck():
try:
# Başlatma ve uzunluğu test et
deck = Deck()
assert len(deck) == 52, f"Deck should have 52 cards, but has {len(deck)}"
# getitem metodunu test et
first_card = deck[0]
assert isinstance(first_card, str), f"Card should be a string, but got {type(first_card)}"
# contains metodunu test et
assert "AS" in deck, "Ace of Spades should be in the deck"
assert "XY" not in deck, "XY is not a valid card and should not be in the deck"
# Yinelemeyi test et
cards = [card for card in deck]
assert len(cards) == 52, f"Iteration should yield 52 cards, but got {len(cards)}"
assert len(set(cards)) == 52, "All cards in the deck should be unique"
# Karıştırmayı test et (sıranın değiştiğine dair temel kontrol)
original_first_five = [deck[i] for i in range(5)]
deck.shuffle()
shuffled_first_five = [deck[i] for i in range(5)]
assert original_first_five != shuffled_first_five or len(deck) <= 5, "Shuffle should change card order"
# Karıştırmanın kart kaybetmediğini kontrol et
assert len(deck) == 52, f"Deck should still have 52 cards after shuffle, but has {len(deck)}"
print("All tests passed!")
except AssertionError as e:
print(f"Test failed: {e}")
test_deck()
print("Tests completed")Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerself ParametresiMetotlarÖzniteliklerYapıcı Metot (__init__)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımsuper() FonksiyonuMetot Geçersiz KılmaÇoklu KalıtımMetot Çözümleme SırasıÖzet - Çalışan Hiyerarşisi7Özel Metotlar
Sihirli Metotlara GirişOperatör Aşırı YüklemeKapsayıcı Sihirli MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım kalıplarına girişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı13Final Meydan Okumaları
E-öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi5Çok Biçimlilik (Polymorphism)
Metot Geçersiz Kılmaya Yeniden BakışDuck TypingSoyut Sınıflar ve MetotlarArayüz TasarımıÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon ve KalıtımMixinsStatik ve Sınıf MetotlarıSınıf DekoratörleriBağlam Yöneticileri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı