Decorator Class
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Python di Coddy. Pelajaran 40 dari 64.
Dekorator class memungkinkan kamu mengubah atau meningkatkan class dengan membungkusnya menggunakan fungsi lain. Cara kerjanya seperti dekorator fungsi, tetapi diterapkan pada seluruh class.
Berikut class sederhana tanpa dekorasi:
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"Buat dekorator class yang menambahkan method baru:
def add_farewell(cls):
def farewell(self):
return f"Goodbye from {self.name}"
cls.farewell = farewell # Tambahkan method ke class
return clsTerapkan decorator ke class menggunakan @:
@add_farewell
class EnhancedPerson:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"Sekarang class ini memiliki method asli dan method tambahan:
person = EnhancedPerson("Alice")
print(person.greet()) # Halo, nama saya Alice
print(person.farewell()) # Salam perpisahan dari AliceKamu juga bisa membungkus method yang sudah ada: menyimpan method aslinya agar kamu tetap bisa memanggilnya di dalam pembungkus. Ini berguna saat kamu ingin menambahkan perilaku (seperti pelacakan atau pencatatan) di sekitar method yang sudah dimiliki class:
def add_tracking(cls):
original_greet = cls.greet # Simpan method asli
def tracked_greet(self):
print(f"greet was called") # Jalankan perilaku tambahan sebelumnya
return original_greet(self) # Panggil method asli
cls.greet = tracked_greet # Ganti method pada class
return cls
@add_tracking
class TrackedPerson:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"Saat kamu memanggil greet sekarang, wrapper dijalankan terlebih dahulu, lalu meneruskan ke fungsi aslinya:
person = TrackedPerson("Alice")
print(person.greet())
# greet dipanggil
# Halo, nama saya AliceLangkah-langkah utama untuk membungkus method yang sudah ada adalah:
1. Simpan method asli: original = cls.method
2. Definisikan fungsi baru yang memanggil original(self) beserta logika tambahan apa pun.
3. Tetapkan kembali fungsi baru ke class: cls.method = new_function
4. Kembalikan class yang telah dimodifikasi.
Poin penting: Decorator class menerima class sebagai input, memodifikasi atau meningkatkannya, lalu mengembalikan class yang telah dimodifikasi. Decorator class dapat menambahkan method, memodifikasi atribut, atau membungkus fungsionalitas yang sudah ada. Gunakan @decorator_name di atas definisi class untuk menerapkannya. Cara ini memberikan pendekatan yang rapi untuk memperluas fungsionalitas class tanpa pewarisan.
Tantangan
SedangDalam tantangan ini, kamu akan menerapkan decorator class yang menambahkan fungsi pelacakan pemanggilan method.
decorator.py- Terapkan decorator classadd_countercalculator.py- Berisi class yang akan menggunakan decoratormu
File driver.py berisi banyak skenario pengujian yang akan memvalidasi penerapanmu dengan berbagai kasus penggunaan, pola pewarisan, dan kasus tepi. Kamu tidak perlu mengubah file ini, tetapi memeriksanya akan membantumu memahami perilaku yang diharapkan.
Coba sendiri
from calculator import Calculator
# Penangan kasus uji yang menyeluruh
test_case = input()
if test_case == "basic_functionality":
calc = Calculator()
print(calc.add(5, 3)) # Seharusnya mencetak 8
print(calc.add(2, 7)) # Seharusnya mencetak 9
print(calc.subtract(10, 4)) # Seharusnya mencetak 6
print(calc.call_counts) # Seharusnya mencetak {'add': 2, 'subtract': 1}
elif test_case == "multiple_instances":
calc1 = Calculator()
calc2 = Calculator()
print(calc1.add(5, 3)) # Seharusnya mencetak 8
print(calc2.add(2, 7)) # Seharusnya mencetak 9
print(calc1.subtract(10, 4)) # Seharusnya mencetak 6
# Kedua instance seharusnya berbagi call_counts yang sama
print(calc1.call_counts) # Seharusnya mencetak {'add': 2, 'subtract': 1}
print(calc2.call_counts) # Seharusnya mencetak {'add': 2, 'subtract': 1}
print(calc1.call_counts is calc2.call_counts) # Seharusnya mencetak True
elif test_case == "method_call_order":
calc = Calculator()
print(calc.add(1, 2)) # Seharusnya mencetak 3
print(calc.subtract(5, 2)) # Seharusnya mencetak 3
print(calc.add(10, 20)) # Seharusnya mencetak 30
print(calc.add(7, 3)) # Seharusnya mencetak 10
print(calc.call_counts) # Seharusnya mencetak {'add': 3, 'subtract': 1}
elif test_case == "large_values":
calc = Calculator()
print(calc.add(1000000, 2000000)) # Seharusnya mencetak 3000000
print(calc.subtract(5000000, 2000000)) # Seharusnya mencetak 3000000
print(calc.call_counts) # Seharusnya mencetak {'add': 1, 'subtract': 1}
elif test_case == "negative_values":
calc = Calculator()
print(calc.add(-5, -3)) # Seharusnya mencetak -8
print(calc.subtract(-10, -4)) # Seharusnya mencetak -6
print(calc.call_counts) # Seharusnya mencetak {'add': 1, 'subtract': 1}
elif test_case == "float_values":
calc = Calculator()
print(calc.add(5.5, 3.2)) # Seharusnya mencetak 8.7
print(calc.subtract(10.5, 4.2)) # Seharusnya mencetak 6.3
print(calc.call_counts) # Seharusnya mencetak {'add': 1, 'subtract': 1}
elif test_case == "zero_values":
calc = Calculator()
print(calc.add(0, 0)) # Seharusnya mencetak 0
print(calc.subtract(0, 0)) # Seharusnya mencetak 0
print(calc.call_counts) # Seharusnya mencetak {'add': 1, 'subtract': 1}
elif test_case == "counter_reset":
calc = Calculator()
print(calc.add(5, 3)) # Seharusnya mencetak 8
print(calc.call_counts) # Seharusnya mencetak {'add': 1, 'subtract': 0}
# Atur ulang penghitung
calc.call_counts = {"add": 0, "subtract": 0}
print(calc.add(2, 7)) # Seharusnya mencetak 9
print(calc.call_counts) # Seharusnya mencetak {'add': 0, 'subtract': 0}
elif test_case == "counter_manipulation":
calc = Calculator()
print(calc.add(5, 3)) # Seharusnya mencetak 8
print(calc.call_counts) # Seharusnya mencetak {'add': 1, 'subtract': 0}
# Ubah penghitung secara langsung
calc.call_counts["add"] = 100
print(calc.add(2, 7)) # Seharusnya mencetak 9
print(calc.call_counts) # Seharusnya mencetak {'add': 101, 'subtract': 0}
elif test_case == "performance_test":
calc = Calculator()
# Lakukan 1000 operasi add
for i in range(1000):
calc.add(i, i+1)
# Lakukan 500 operasi subtract
for i in range(500):
calc.subtract(i+10, i)
print(calc.call_counts) # Seharusnya mencetak {'add': 1000, 'subtract': 500}Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalPengantar OOPclass vs objectParameter selfmethodAtributMethod Konstruktor (__init__)Rangkuman: Kalkulator Sederhana4Pewarisan
Pewarisan DasarFungsi super()Penimpaan MethodPewarisan BergandaUrutan Resolusi MethodRingkasan: Hierarki Karyawan5Polimorfisme
Meninjau Ulang Method OverridingDuck Typingclass dan method AbstrakDesain InterfaceRingkasan: Kalkulator Bentuk8Konsep OOP Lanjutan
Komposisi vs PewarisanMixinsMetode Statis dan Metode ClassDecorator ClassPengelola Konteks11Pola Desain Bagian 2
Pola PerintahPola AdapterPola DecoratorPola Template MethodPola StatePola Composite3Property class
Variabel instance vs variabel classDekorator propertyAtribut privatRangkuman: Pengelola Rekening Bank6Enkapsulasi
Anggota Public, Protected, PrivateModifier AksesPenyembunyian InformasiDecorator Property Tingkat LanjutUlasan: Sistem Catatan Siswa12Proyek: Manajemen Perpustakaan
Ikhtisar Proyekclass Buku dan PenggunaSistem PeminjamanFitur PencarianAntarmuka AdminPengujian dan IntegrasiLatihan sendiri: Compiler Python online