Decorator Property Tingkat Lanjut
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Python di Coddy. Pelajaran 31 dari 64.
Decorator property tingkat lanjut memberikan kontrol yang lebih canggih atas akses atribut, termasuk property terhitung, penghapus, dan pengelolaan property secara menyeluruh.
Berikut contoh property terhitung yang menghasilkan nilai dari atribut lain:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
@property
def perimeter(self):
return 2 * (self.width + self.height)Gunakan property hasil perhitungan seperti atribut biasa:
rect = Rectangle(5, 3)
print(rect.area) # 15, dihitung secara otomatis
print(rect.perimeter) # 16, dihitung secara otomatisBuat property dengan getter, setter, dan deleter:
class Temperature:
def __init__(self):
self._temp = 0
@property
def temperature(self):
return self._temp
@temperature.setter
def temperature(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
self._temp = value
@temperature.deleter
def temperature(self):
print("Resetting temperature to 0")
self._temp = 0Gunakan seluruh fungsionalitas property:
temp = Temperature()Gunakan setter dengan validasi:
temp.temperature = 25
print(temp.temperature) # 25
# temp.temperature = -300 # Akan memunculkan ValueErrorGunakan deleter:
del temp.temperature
print(temp.temperature) # 0Buat contoh yang lebih kompleks dengan skor permainan:
class Player:
def __init__(self, name):
self.name = name
self._score = 0
self._level = 1
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if value >= 0:
self._score = value
self._level = (value // 1000) + 1
else:
raise ValueError("Score cannot be negative")
@score.deleter
def score(self):
print(f"Resetting {self.name}'s progress")
self._score = 0
self._level = 1
@property
def level(self):
return self._level
player = Player("Alice")
player.score = 2500
print(f"Score: {player.score}, Level: {player.level}") # Score: 2500, Level: 3
del player.score
print(f"Score: {player.score}, Level: {player.level}") # Score: 0, Level: 1Output:
15
16
25
Resetting temperature to 0
0
Score: 2500, Level: 3
Resetting Alice's progress
Score: 0, Level: 1Poin Penting: Dekorator property tingkat lanjut memungkinkan property terhitung (dihitung dari data lain), penghapusan property dengan @property.deleter, serta kontrol penuh atas pengambilan, pengaturan, dan penghapusan atribut. Ini menciptakan antarmuka yang intuitif sekaligus mempertahankan validasi data dan enkapsulasi yang kuat.
Tantangan
SedangDalam tantangan ini, kamu akan mengimplementasikan class Rectangle dengan enkapsulasi dan validasi property yang tepat.
rectangle.py- Ini adalah file yang perlu kamu edit, berisi komentar TODO untuk memandu implementasimudriver.py- Berisi berbagai skenario pengujian (jangan diubah)
- Simpan nilai dalam atribut terlindungi (internal)
_widthdan_height - Buat property untuk
widthdanheightdengan validasi (harus positif)- Tampilkan pesan ValueError yang sesuai seperti yang ditentukan dalam TODO
- Penting: Periksa apakah nilai kurang dari atau sama dengan 0, lalu tampilkan error (ini memastikan perilaku yang konsisten)
- Implementasikan property hanya-baca untuk
areadanperimeter - Buat property
dimensionsdengan fungsi getter, setter, dan deleter seperti yang dijelaskan dalam TODO- Penting: Di setter, gunakan sintaks tuple unpacking:
width, height = dimensions
- Penting: Di setter, gunakan sintaks tuple unpacking:
Coba sendiri
from rectangle import Rectangle
# Penangan kasus uji
test_case = input()
# Uji fungsi dasar
if test_case == "default_test":
rect = Rectangle(5, 3)
print(f"Width: {rect.width}, Height: {rect.height}")
print(f"Area: {rect.area}, Perimeter: {rect.perimeter}")
# Uji property dimensions
print(f"Dimensions: {rect.dimensions}")
rect.dimensions = (10, 8)
print(f"New area: {rect.area}")
# Uji validasi
try:
rect.width = -2
except ValueError as e:
print(f"Validation error: {e}")
# Uji deleter
del rect.dimensions
print(f"After reset: {rect.dimensions}")
# Uji dengan nilai nol
elif test_case == "zero_values":
try:
rect = Rectangle(0, 5)
except ValueError as e:
print(f"Error creating rectangle: {e}")
try:
rect = Rectangle(5, 0)
except ValueError as e:
print(f"Error creating rectangle: {e}")
# Uji dengan nilai negatif
elif test_case == "negative_values":
rect = Rectangle(5, 3)
original_dimensions = rect.dimensions
try:
rect.dimensions = (5, -3)
except ValueError as e:
print(f"Error setting dimensions: {e}")
print(f"Dimensions after failed update: {rect.dimensions}")
print(f"Original dimensions preserved: {rect.dimensions == original_dimensions}")
# Uji dengan nilai besar
elif test_case == "large_values":
rect = Rectangle(1000000, 2000000)
print(f"Large rectangle area: {rect.area}")
print(f"Large rectangle perimeter: {rect.perimeter}")
# Uji dengan nilai pecahan
elif test_case == "float_values":
rect = Rectangle(3.5, 2.75)
print(f"Dimensions: {rect.dimensions}")
print(f"Area: {rect.area}")
print(f"Perimeter: {rect.perimeter}")
rect.dimensions = (1.1, 2.2)
print(f"New area with float dimensions: {rect.area}")
# Uji dengan error tipe data
elif test_case == "type_errors":
try:
rect = Rectangle("5", 3)
except Exception as e:
print(f"Type error during creation: {type(e).__name__}: {e}")
rect = Rectangle(5, 3)
try:
rect.dimensions = 10 # Bukan tuple
except Exception as e:
print(f"Type error setting dimensions: {type(e).__name__}: {e}")
# Uji beberapa operasi property
elif test_case == "property_operations":
rect = Rectangle(5, 10)
print(f"Initial - Width: {rect.width}, Height: {rect.height}, Area: {rect.area}")
rect.width = 8
print(f"After width change - Width: {rect.width}, Area: {rect.area}")
rect.height = 6
print(f"After height change - Height: {rect.height}, Area: {rect.area}")
rect.dimensions = (12, 9)
print(f"After dimensions change - Dimensions: {rect.dimensions}, Area: {rect.area}")
del rect.dimensions
print(f"After reset - Dimensions: {rect.dimensions}, Area: {rect.area}")
# Uji kasus tepi validasi property
elif test_case == "validation_edge_cases":
rect = Rectangle(5, 3)
try:
rect.width = 0
except ValueError as e:
print(f"Zero width error: {e}")
# Nilai positif yang sangat kecil harus diterima
rect.height = 0.0001
print(f"Small height accepted: {rect.height}")
print(f"Area with small height: {rect.area}")
# Uji beberapa persegi panjang
elif test_case == "multiple_rectangles":
rect1 = Rectangle(5, 3)
rect2 = Rectangle(10, 2)
rect3 = Rectangle(4, 4)
print(f"Rectangle 1 - Area: {rect1.area}, Perimeter: {rect1.perimeter}")
print(f"Rectangle 2 - Area: {rect2.area}, Perimeter: {rect2.perimeter}")
print(f"Rectangle 3 - Area: {rect3.area}, Perimeter: {rect3.perimeter}")
# Ubah setiap persegi panjang
rect1.width = 7
rect2.height = 5
rect3.dimensions = (6, 6)
print(f"After modifications:")
print(f"Rectangle 1 - Dimensions: {rect1.dimensions}")
print(f"Rectangle 2 - Dimensions: {rect2.dimensions}")
print(f"Rectangle 3 - Dimensions: {rect3.dimensions}")
# Uji performa dengan banyak operasi
elif test_case == "performance_test":
rect = Rectangle(5, 5)
# Lakukan banyak operasi property
for i in range(1000):
rect.width = i % 10 + 1 # Nilai 1-10
rect.height = i % 5 + 1 # Nilai 1-5
area = rect.area # Akses property yang dihitung
perimeter = rect.perimeter # Akses property yang dihitung
dims = rect.dimensions # Akses getter property
print(f"Final state after 1000 operations:")
print(f"Width: {rect.width}, Height: {rect.height}")
print(f"Area: {rect.area}, Perimeter: {rect.perimeter}")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