Introducere
În această lecție, vom explora conceptele avansate de proprietăți, setteri și getteri în limbajul de programare Python. Aceste concepte sunt importante pentru a înțelege mecanismele de control al accesului la atributele unei clase și pentru a implementa o interfață sigură și corectă pentru utilizatorii acestei clase.
Cuprins
- Recapitulare a proprietăților, setterilor și getterilor
- Proprietăți avansate
- Setteri și getteri avansați
- Exemple și scenarii de utilizare
- Încheiere și concluzii
1. Recapitulare a proprietăților, setterilor și getterilor
Înainte de a discuta despre proprietăți, setteri și getteri avansați, să revedem rapid conceptele de bază. Proprietățile sunt folosite pentru a controla accesul la atributele unei clase, oferind o interfață publică pentru atributele private.
Setterii și getterii sunt metode care permit modificarea și citirea valorilor atributelor, respectiv. În Python, putem utiliza decoratorii @property și @<attribute>.setter pentru a defini setteri și getteri pentru atributele noastre.
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
circle = Circle(5)
print(circle.radius) # Getter
circle.radius = 10 # Setter
2. Proprietăți avansate
Proprietățile avansate ne permit să implementăm logica suplimentară în setteri și getteri, cum ar fi validarea datelor, actualizarea altor atribute sau declanșarea anumitor acțiuni în funcție de valorile atributelor.
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
print("Getting radius")
return self._radius
@radius.setter
def radius(self, value):
print("Setting radius")
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
return self._radius * 2
circle = Circle(5)
print(circle.radius)
circle.radius = 10
print(circle.diameter)
3. Setteri și getteri avansați
Putem folosi setteri și getteri avansați pentru a crea o interfață de lucru cu atributele clasei care sunt mai complexe sau au o anumită logică asociată. De exemplu, putem crea o clasă Date care validează datele introduse și oferă o interfață pentru a modifica și accesa componentele datei.
class Date:
def __init__(self, day, month, year):
self._day = day
self._month = month
self._year = year
@property
def day(self):
return self._day
@day.setter
def day(self, value):
if value < 1 or value > 31:
raise ValueError("Invalid day value")
self._day = value
@property
def month(self):
return self._month
@month.setter
def month(self, value):
if value < 1 or value > 12:
raise ValueError("Invalid month value")
self._month = value
@property
def year(self):
return self._year
@year.setter
def year(self, value):
if value < 0:
raise ValueError("Invalid year value")
self._year = value
date = Date(1, 1, 2022)
print(date.day, date.month, date.year)
date.day = 15
date.month = 6
date.year = 2023
print(date.day, date.month, date.year)
4. Exemple și scenarii de utilizare
4.1. Validarea datelor
Un caz de utilizare important pentru setteriși getteri avansați este validarea datelor. De exemplu, putem crea o clasă Employee care validează numele și vârsta angajaților:
class Employee:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not isinstance(value, str) or len(value.strip()) == 0:
raise ValueError("Invalid name")
self._name = value.strip()
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int) or value < 18:
raise ValueError("Invalid age")
self._age = value
emp = Employee("John Doe", 30)
print(emp.name, emp.age)
emp.name = "Jane Smith"
emp.age = 25
print(emp.name, emp.age)
4.2. Calcularea valorilor derivate
Un alt caz de utilizare pentru proprietăți este calcularea valorilor derivate din alte atribute ale clasei. De exemplu, putem crea o clasă Rectangle care calculează aria și perimetrul în funcție de lățime și înălțime:
class Rectangle:
def __init__(self, width, height):
self._width = width
self._height = height
@property
def width(self):
return self._width
@width.setter
def width(self, value):
if value < 0:
raise ValueError("Width cannot be negative")
self._width = value
@property
def height(self):
return self._height
@height.setter
def height(self, value):
if value < 0:
raise ValueError("Height cannot be negative")
self._height = value
@property
def area(self):
return self._width * self._height
@property
def perimeter(self):
return 2 * (self._width + self._height)
rect = Rectangle(5, 3)
print(rect.width, rect.height, rect.area, rect.perimeter)
rect.width = 10
rect.height = 6
print(rect.width, rect.height, rect.area, rect.perimeter)
5. Încheiere și concluzii
În această lecție, am discutat despre proprietăți, setteri și getteri avansați în Python și am analizat câteva exemple și scenarii de utilizare relevante. Aceste concepte ne permit să controlăm accesul la atributele noastre și să implementăm logica suplimentară pentru a asigura o interfață sigură și corectă pentru utilizatorii claselor noastre.
Prin utilizarea proprietăților, setterilor și getterilor în mod corespunzător, putem crea clase mai robuste și mai ușor de utilizat, care protejează datele și oferă o interfață clară pentru colaborarea cu alte părți ale codului nostru.