class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""Get the radius"""
return self._radius
c = Circle(5)
print(c.radius) # 5 (no parentheses!)
# c.radius = 10 # AttributeError! No setter definedclass Temperature:
def __init__(self, celsius=0):
self._celsius = celsius
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, value):
if value < -273.15:
raise ValueError('Below absolute zero!')
self._celsius = value
@property
def fahrenheit(self):
return self._celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
self.celsius = (value - 32) * 5/9 # Reuses celsius setter!
t = Temperature(100)
print(t.fahrenheit) # 212.0
t.fahrenheit = 32 # Uses fahrenheit setter
print(t.celsius) # 0.0
# t.celsius = -300 # ValueError!class File:
def __init__(self, name):
self._name = name
self._loaded = True
@property
def name(self):
if not self._loaded:
raise RuntimeError('File has been deleted')
return self._name
@name.deleter
def name(self):
print(f'Deleting {self._name}...')
self._loaded = False
f = File('data.txt')
print(f.name) # 'data.txt'
del f.name # 'Deleting data.txt...'
# print(f.name) # RuntimeError!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)
@property
def is_square(self):
return self.width == self.height
r = Rectangle(4, 5)
print(r.area) # 20 (no parentheses!)
print(r.is_square) # Falseclass User:
def __init__(self, first, last):
self.first = first
self.last = last
@property
def full_name(self):
return f'{self.first} {self.last}'
# No setter — read-only!
u = User('John', 'Doe')
print(u.full_name) # 'John Doe'
# u.full_name = 'X' # AttributeError!Create a `Product` class with `__init__(self, name, price, discount_percent)`. Store price as `self._price` and discount as `self._discount`. Create: `@property price` (getter), `@price.setter` (validates price > 0), `@property discount` (getter), `@discount.setter` (validates 0-100), `@property final_price` (computed: price * (1 - discount/100), read-only). Demonstrate valid/invalid assignments and computed final_price.