Sınıf Dekoratörleri
Coddy'nin Python Journey'sinin Object Oriented Programming bölümünün bir parçası. Ders 40 / 64.
class decorator'ları, class'ları başka bir function ile sararak onları Modify veya Enhance etmenize olanak tanır. Bunlar function decorator'ları gibi çalışır, ancak tüm class'lara uygulanır.
İşte dekoratör kullanılmamış basit bir class:
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"Yeni bir method ekleyen bir class decorator oluşturun:
def add_farewell(cls):
def farewell(self):
return f"Goodbye from {self.name}"
cls.farewell = farewell # Metodu sınıfa ekle
return cls@ kullanarak decorator'ı bir class'a uygulayın:
@add_farewell
class EnhancedPerson:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"Şimdi class'ın both original ve added methods'i var:
person = EnhancedPerson("Alice")
print(person.greet()) # Merhaba, benim adım Alice
print(person.farewell()) # Alice'den hoşça kalAyrıca mevcut bir method'u sarabilirsiniz: orijinal olanı saklayarak onu sarmalayıcı içinde yine çağırabilirsiniz. Bu, class'ın zaten sahip olduğu bir method'un etrafına behaviour (izleme veya günlük kaydı gibi) eklemek istediğinizde kullanışlıdır:
def add_tracking(cls):
original_greet = cls.greet # Orijinal metodu sakla
def tracked_greet(self):
print(f"greet was called") # Önce ekstra davranış
return original_greet(self) # Orijinal metodu çağır
cls.greet = tracked_greet # Sınıftaki metodu değiştir
return cls
@add_tracking
class TrackedPerson:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"Şimdi greet çağrıldığında, önce sarmalayıcı çalışır, ardından özgün işlevi çağırır:
person = TrackedPerson("Alice")
print(person.greet())
# greet çağrıldı
# Merhaba, benim adım AliceMevcut bir method'u sarmalamak için temel adımlar şunlardır:
1. original method'u kaydedin: original = cls.method
2. original(self)'i ve ek mantığı çağıran yeni bir işlev tanımlayın.
3. Yeni işlevi sınıfa geri atayın: cls.method = new_function
4. modified sınıfı döndürün.
Önemli Nokta: Sınıf dekoratörleri, bir sınıfı input olarak alır, onu değiştirir veya geliştirir ve modified class'ı döndürür. methods ekleyebilir, öznitelikleri değiştirebilir veya mevcut functionality'yi sarmalayabilirler. Bunları uygulamak için class definition'ın üstüne @decorator_name yazın. Bu, kalıtım kullanmadan class functionality'sini genişletmek için temiz bir yol sağlar.
Görev
OrtaBu görevde, yöntem çağrılarını izleme işlevselliği ekleyen bir sınıf decorator'ı uygulayacaksın.
decorator.py-add_countersınıf decorator'ını uygulacalculator.py- decorator'ını kullanacak sınıfları içerir
driver.py dosyası, uygulamanı çeşitli kullanım durumlarına, kalıtım düzenlerine ve uç durumlara karşı doğrulayacak kapsamlı test senaryoları içerir. Bu dosyada değişiklik yapmana gerek yok, ancak dosyayı incelemek beklenen davranışı anlamana yardımcı olacaktır.
Kendin dene
from calculator import Calculator
# Kapsamlı test durumu işleyicisi
test_case = input()
if test_case == "basic_functionality":
calc = Calculator()
print(calc.add(5, 3)) # 8 yazdırmalı
print(calc.add(2, 7)) # 9 yazdırmalı
print(calc.subtract(10, 4)) # 6 yazdırmalı
print(calc.call_counts) # Should print {'add': 2, 'subtract': 1}
elif test_case == "multiple_instances":
calc1 = Calculator()
calc2 = Calculator()
print(calc1.add(5, 3)) # 8 yazdırmalı
print(calc2.add(2, 7)) # 9 yazdırmalı
print(calc1.subtract(10, 4)) # 6 yazdırmalı
# Her iki örnek de aynı call_counts'u paylaşmalı
print(calc1.call_counts) # Should print {'add': 2, 'subtract': 1}
print(calc2.call_counts) # Should print {'add': 2, 'subtract': 1}
print(calc1.call_counts is calc2.call_counts) # True yazdırmalı
elif test_case == "method_call_order":
calc = Calculator()
print(calc.add(1, 2)) # 3 yazdırmalı
print(calc.subtract(5, 2)) # 3 yazdırmalı
print(calc.add(10, 20)) # 30 yazdırmalı
print(calc.add(7, 3)) # 10 yazdırmalı
print(calc.call_counts) # Should print {'add': 3, 'subtract': 1}
elif test_case == "large_values":
calc = Calculator()
print(calc.add(1000000, 2000000)) # 3000000 yazdırmalı
print(calc.subtract(5000000, 2000000)) # 3000000 yazdırmalı
print(calc.call_counts) # Should print {'add': 1, 'subtract': 1}
elif test_case == "negative_values":
calc = Calculator()
print(calc.add(-5, -3)) # -8 yazdırmalı
print(calc.subtract(-10, -4)) # -6 yazdırmalı
print(calc.call_counts) # Should print {'add': 1, 'subtract': 1}
elif test_case == "float_values":
calc = Calculator()
print(calc.add(5.5, 3.2)) # 8.7 yazdırmalı
print(calc.subtract(10.5, 4.2)) # 6.3 yazdırmalı
print(calc.call_counts) # Should print {'add': 1, 'subtract': 1}
elif test_case == "zero_values":
calc = Calculator()
print(calc.add(0, 0)) # 0 yazdırmalı
print(calc.subtract(0, 0)) # 0 yazdırmalı
print(calc.call_counts) # Should print {'add': 1, 'subtract': 1}
elif test_case == "counter_reset":
calc = Calculator()
print(calc.add(5, 3)) # 8 yazdırmalı
print(calc.call_counts) # Should print {'add': 1, 'subtract': 0}
# Sayacı sıfırla
calc.call_counts = {"add": 0, "subtract": 0}
print(calc.add(2, 7)) # 9 yazdırmalı
print(calc.call_counts) # Should print {'add': 0, 'subtract': 0}
elif test_case == "counter_manipulation":
calc = Calculator()
print(calc.add(5, 3)) # 8 yazdırmalı
print(calc.call_counts) # Should print {'add': 1, 'subtract': 0}
# Sayacı doğrudan manipüle et
calc.call_counts["add"] = 100
print(calc.add(2, 7)) # 9 yazdırmalı
print(calc.call_counts) # Should print {'add': 101, 'subtract': 0}
elif test_case == "performance_test":
calc = Calculator()
# 1000 add işlemi gerçekleştir
for i in range(1000):
calc.add(i, i+1)
# 500 subtract işlemi gerçekleştir
for i in range(500):
calc.subtract(i+10, i)
print(calc.call_counts) # Should print {'add': 1000, 'subtract': 500}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ıKendi başına pratik yap: Online Python derleyicisi