Sınıf Dekoratörleri
Coddy'nin Python Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 40 / 64.
Sınıf dekoratörleri, sınıfları başka bir işlevle sarmalayarak değiştirmenize veya geliştirmenize olanak tanır. İşlev dekoratörleri gibi çalışırlar, ancak sınıfların tamamına uygulanırlar.
İşte dekorasyon içermeyen basit bir sınıf:
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"Yeni bir yöntem ekleyen bir sınıf dekoratörü oluşturun:
def add_farewell(cls):
def farewell(self):
return f"Goodbye from {self.name}"
cls.farewell = farewell # Metodu sınıfa ekle
return clsDekoratörü @ kullanarak bir sınıfa uygulayın:
@add_farewell
class EnhancedPerson:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"Artık sınıf hem özgün hem de eklenen yöntemlere sahip:
person = EnhancedPerson("Alice")
print(person.greet()) # Merhaba, benim adım Alice
print(person.farewell()) # Alice'den hoşça kalAyrıca mevcut bir yöntemi sarmalayabilirsiniz: özgün yöntemi saklayarak sarmalayıcının içinde onu yine çağırabilirsiniz. Bu, sınıfın zaten sahip olduğu bir yöntemin etrafına davranış (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 yöntemi sarmalamak için temel adımlar şunlardır:
1. Özgün yöntemi kaydedin: original = cls.method
2. original(self) çağrısını ve ek mantığı içeren yeni bir işlev tanımlayın.
3. Yeni işlevi sınıfa geri atayın: cls.method = new_function
4. Değiştirilmiş sınıfı döndürün.
Temel Nokta: Sınıf dekoratörleri girdi olarak bir sınıf alır, onu değiştirir veya geliştirir ve değiştirilmiş sınıfı döndürür. Metotlar ekleyebilir, öznitelikleri değiştirebilir veya mevcut işlevselliği sarabilirler. Bunları uygulamak için sınıf tanımının üstüne @decorator_name ekleyin. Bu, kalıtım kullanmadan sınıf işlevselliğini 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 dekoratörü uygulayacaksın.
decorator.py-add_countersınıf dekoratörünü uygulacalculator.py- Dekoratörünü kullanacak sınıfları içerir
driver.py dosyası, uygulamanı çeşitli kullanım durumları, kalıtım biçimleri 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.
Nesne Yönelimli Programlama 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