-
Introducere în descriptori
- Ce sunt descriptorii și de ce sunt utili
- Exemple de descriptori în Python (
property,staticmethod,classmethod, etc.) - Cum funcționează mecanismul descriptorilor
-
Crearea unui descriptor simplu
- Metodele descriptorilor:
__get__,__set__și__delete__ - Exemplu: descriptor pentru validarea atributelor
- Exercițiu: creați un descriptor pentru gestionarea atributelor numerice
- Metodele descriptorilor:
-
Crearea unui descriptor read-only
- Cum să creați un descriptor care nu poate fi modificat
- Exemplu: descriptor pentru calcularea ariei unui dreptunghi
- Exercițiu: creați un descriptor pentru calcularea lungimii unui vector
-
Crearea unui descriptor cu proprietăți avansate
- Cum să adăugați proprietăți avansate la un descriptor
- Exemplu: descriptor pentru gestionarea memoriei cache
- Exercițiu: creați un descriptor pentru gestionarea versiunilor unui obiect
-
Utilizarea descriptorilor în clase de bază și clase derivate
- Cum să folosiți descriptori în clase de bază și clase derivate
- Exemplu: descriptor pentru validarea atributelor într-o ierarhie de clase
- Exercițiu: creați un descriptor pentru gestionarea atributelor într-o ierarhie de clase geometrice
-
Descriptori și metode de clasă
- Cum să creați descriptori care funcționează cu metode de clasă
- Exemplu: descriptor pentru înregistrarea apelurilor la metode de clasă
- Exercițiu: creați un descriptor pentru gestionarea log-urilor în metodele de clasă
Exemple și exerciții pentru fiecare subpunct:
Exemplu: descriptor pentru validarea atributelor
class ValidarePozitiv:
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
if value < 0:
raise ValueError("Valoarea trebuie să fie pozitivă")
instance.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class Numar:
valoare = ValidarePozitiv()
n = Numar()
n.valoare = 5 # Funcționează corect
n.valoare = -2 # Ridică ValueError: Valoarea trebuie să fie pozitivă
Exercițiu:
Creați un descriptor pentru gestionarea atributelor numerice. Acest descriptor ar trebui să permită doar valori numerice și să ridice o excepție atunci când se încearcă atribuirea unei valori non-numerice.
Exemplu: descriptor pentru calcularea ariei unui dreptunghi
class Arie:
def __get__(self, instance, owner):
return instance.lungime * instance.latime
class Dreptunghi:
def __init__(self, lungime, latime):
self.lungime = lungime
self.latime = latime
arie = Arie()
d = Dreptunghi(4, 5)
print(d.arie) # 20
Exercițiu:
Creați un descriptor pentru calcularea lungimii unui vector într-o clasă Vector. Acest descriptor ar trebui să fie read-only și să calculeze lungimea vectorului pe baza componentelor sale.
Exemplu: descriptor pentru gestionarea memoriei cache
class Cache:
def __init__(self, func):
self.func = func
self.cache = {}
def __get__(self, instance, owner):
if instance not in self.cache:
self.cache[instance] = self.func(instance)
return self.cache[instance]
class Fibonacci:
def __init__(self, n):
self.n = n
@Cache
def fib(self):
if self.n <= 1:
return self.n
f1 = Fibonacci(self.n - 1)
f2 = Fibonacci(self.n - 2)
return f1.fib + f2.fib
f = Fibonacci(10)
print(f.fib) # 55
Exercițiu:
Creați un descriptor pentru gestionarea versiunilor unui obiect. Acest descriptor ar trebui să mențină o listă de versiuni anterioare ale obiectului și să permită accesarea acestora prin index.
Exemplu: descriptor pentru înregistrarea apelurilor la metode de clasă
class InregistrareApeluri:
def __init__(self, func):
self.func = func
self.numar_apeluri = 0
def __get__(self, instance, owner):
self.numar_apeluri += 1
return self.func.__get__(instance, owner)
class Exemplu:
@classmethod
def metoda(cls):
print("Metoda apelată")
metoda = InregistrareApeluri(metoda)
Exemplu.metoda() # Metoda apelată
Exemplu.metoda() # Metoda apelată
print(Exemplu.metoda.numar_apeluri) # 2
Exercițiu:
Creați un descriptor pentru gestionarea log-urilor în metodele de clasă. Acest descriptor ar trebui să înregistreze fiecare apel la o metodă de clasă și să permită accesarea log-urilor prin metoda afisare_loguri().