Conținut curs
Gestionarea erorilor și excepțiilor
0/1
Python Intermediar
Despre lecție

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

  1. Recapitulare a proprietăților, setterilor și getterilor
  2. Proprietăți avansate
  3. Setteri și getteri avansați
  4. Exemple și scenarii de utilizare
  5. Î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.

python
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.

python
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.

python
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:

python
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:

python
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.