Metodi magici in Python

Metodi magici in Python

Questo articolo spiega i metodi magici in Python.

YouTube Video

Metodi magici in Python

I metodi magici (o metodi speciali) in Python sono metodi con un nome speciale usati per fornire alle classi un comportamento unico. Ad esempio, sono caratterizzati dall’essere racchiusi tra due underscore (dunders), come __init__ e __str__. Per questo motivo sono anche chiamati metodi dunder.

Definendo i metodi magici, puoi personalizzare il comportamento standard delle classi. Ad esempio, definire __add__ ti permette di modificare il comportamento dell’operatore +.

Metodi magici per l’inizializzazione e la rappresentazione in stringa

__init__: Metodo di inizializzazione

Il metodo __init__ è un costruttore chiamato automaticamente quando viene creata un’istanza.

1class Person:
2    def __init__(self, name, age):
3        self.name = name
4        self.age = age
5
6person = Person("Alice", 30)
7print(person.name)  # Alice

__str__: Rappresentazione in stringa leggibile

Il metodo __str__ restituisce una rappresentazione in stringa leggibile dall’uomo. Viene chiamato da print() e str().

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __str__(self):
6        return f"Person: {self.name}"
7
8person = Person("Bob")
9print(person)  # Person: Bob

__repr__: Rappresentazione in stringa per il debug

Il metodo __repr__ restituisce una rappresentazione in stringa a fini di debug. Viene utilizzato da repr() e nella visualizzazione all’interno dell’interprete.

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __repr__(self):
6        return f"Person(name={self.name!r})"
7
8person = Person("Eve")
9print(repr(person))  # Person(name='Eve')

Overloading degli operatori aritmetici

__add__: Operatore +

Usando i metodi magici, è possibile fare l’overloading degli operatori aritmetici. Ad esempio, il metodo __add__ permette di fare l’overloading dell’operatore +.

 1class Vector:
 2    def __init__(self, x, y):
 3        self.x = x
 4        self.y = y
 5
 6    def __add__(self, other):
 7        return Vector(self.x + other.x, self.y + other.y)
 8
 9    def __repr__(self):
10        return f"Vector({self.x}, {self.y})"
11
12    # Other arithmetic magic methods:
13    # def __sub__(self, other):       # Subtraction (-)
14    # def __mul__(self, other):       # Multiplication (*)
15    # def __truediv__(self, other):   # True division (/)
16    # def __floordiv__(self, other):  # Floor division (//)
17    # def __mod__(self, other):       # Modulo (%)
18    # def __pow__(self, other):       # Exponentiation (**)
19
20v1 = Vector(1, 2)
21v2 = Vector(3, 4)
22print(v1 + v2)  # Vector(4, 6)

Altri metodi magici aritmetici includono i seguenti:.

Metodo Operatore
__add__ +
__sub__ -
__mul__ *
__truediv__ /
__floordiv__ //
__mod__ %
__pow__ **

Personalizzazione degli operatori di confronto

Puoi anche fare l’overloading degli operatori di confronto. Ad esempio, il metodo __eq__ permette di fare l’overloading dell’operatore di uguaglianza.

 1class Box:
 2    def __init__(self, volume):
 3        self.volume = volume
 4
 5    def __eq__(self, other):
 6        return self.volume == other.volume
 7
 8    def __lt__(self, other):
 9        return self.volume < other.volume
10
11    # Comparison magic methods:
12    # def __eq__(self, other):  # Equal to (==)
13    # def __ne__(self, other):  # Not equal to (!=)
14    # def __lt__(self, other):  # Less than (<)
15    # def __le__(self, other):  # Less than or equal to (<=)
16    # def __gt__(self, other):  # Greater than (>)
17    # def __ge__(self, other):  # Greater than or equal to (>=)
18
19b1 = Box(100)
20b2 = Box(200)
21
22print(b1 == b2)  # False
23print(b1 < b2)   # True

Esistono anche i seguenti metodi magici:. Questi metodi magici definiscono confronti come l’uguaglianza e l’ordine tra oggetti.

Operatore Metodo magico
== __eq__
!= __ne__
< __lt__
<= __le__
> __gt__
>= __ge__

Metodi magici per i tipi contenitori

Puoi creare classi che si comportano come liste o dizionari.

__len__: Ottenere il numero di elementi

Il metodo __len__ è un metodo magico che restituisce il numero di elementi.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __len__(self):
6        return len(self.items)
7
8basket = Basket(["apple", "banana"])
9print(len(basket))  # 2

__getitem__: Accesso tramite indice

Il metodo __getitem__ viene chiamato quando si utilizza l’accesso tramite indice.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __getitem__(self, index):
6        return self.items[index]
7
8basket = Basket(["apple", "banana"])
9print(basket[1])  # banana

__setitem__ e __delitem__: Scrittura ed eliminazione

I metodi __setitem__ e __delitem__ vengono chiamati quando si scrivono o si eliminano elementi.

 1class Basket:
 2    def __init__(self, items):
 3        self.items = items
 4
 5    def __setitem__(self, index, value):
 6        self.items[index] = value
 7
 8    def __delitem__(self, index):
 9        del self.items[index]
10
11basket = Basket(["apple", "banana"])
12basket[1] = "grape"
13del basket[0]
14print(basket.items)  # ['grape']

Metodi magici per l’iterazione

Per rendere un oggetto iterabile in un ciclo for, implementa quanto segue:.

__iter__ e __next__

 1class Counter:
 2    def __init__(self, limit):
 3        self.limit = limit
 4        self.current = 0
 5
 6    def __iter__(self):
 7        return self
 8
 9    def __next__(self):
10        if self.current >= self.limit:
11            raise StopIteration
12        self.current += 1
13        return self.current
14
15for num in Counter(3):
16    print(num)
17# Output:
18# 1
19# 2
20# 3

Gestore di contesto (istruzione with)

Definendo i metodi __enter__ e __exit__, puoi implementare la logica di pre- e post-elaborazione per l’istruzione with.

 1class FileOpener:
 2    def __init__(self, filename):
 3        self.filename = filename
 4
 5    def __enter__(self):
 6        self.file = open(self.filename, 'r')
 7        return self.file
 8
 9    def __exit__(self, exc_type, exc_val, exc_tb):
10        self.file.close()
11
12with FileOpener("example.txt") as f:
13    content = f.read()
14    print(content)

Oggetti chiamabili: __call__

Definendo il metodo __call__, è possibile rendere un’istanza chiamabile come una funzione.

1class Greeter:
2    def __init__(self, greeting):
3        self.greeting = greeting
4
5    def __call__(self, name):
6        return f"{self.greeting}, {name}!"
7
8hello = Greeter("Hello")
9print(hello("Alice"))  # Hello, Alice!

Riepilogo

I metodi magici in Python sono un modo potente per aggiungere comportamenti naturali e intuitivi alle classi. Ogni metodo ha uno scopo preciso e implementandoli correttamente puoi scrivere codice più flessibile e Pythonic.

I metodi magici fungono da ‘interfaccia invisibile’ che supporta il modo in cui gli oggetti Python interagiscono e si comportano dietro le quinte.

Puoi seguire l'articolo sopra utilizzando Visual Studio Code sul nostro canale YouTube. Controlla anche il nostro canale YouTube.

YouTube Video