eistono dei metodi speciali li riconosci dalle due __
sono metodi non vengono chiamati direttamente dal programmatore ma vengono invocati da Python in situazioni particolari

metori: operatori
vengono utilizzati quando si usa un operatore con un oggetto creato in cui vengono definiti questi metodi

esempio: operatore aritmetici addizione
creiamo una classe e svuluppiamo i metodi __add__ __radd__ __iadd__


codice classe
# definiamo una classe Team
class Team:
# definiamo un __init__ che assegna i membri all'istanza
def __init__(self, members):
self.members = members

# definiamo un __repr__ che restituisce il tipo dell'oggetto
# e i nomi dei membri del team
def __repr__(self):
names = ', '.join([p.name for p in self.members])
return '<Team object [{}]>'.format(names)

# definiamo un __contains__ che restituisce True se un membro
# fa parte del team, altrimenti False
def __contains__(self, other):
return other in self.members

# definiamo un __add__ che restituisce un nuovo team creato
# dall'aggiunta di una nuova persona o dall'unione di 2 team
def __add__(self, other):
if isinstance(other, Person):
return Team(self.members + [other])
elif isinstance(other, Team):
return Team(self.members + other.members)
else:
raise TypeError("Can't add Team with {!r}.".format(other))

# definiamo un __radd__ che è uguale ad __add__, visto che
# l'addizione è un'operazione commutativa
__radd__ = __add__

# definiamo un __iadd__ che modifica il team aggiungendo una
# nuova persona o i membri di un altro team al team corrente
def __iadd__(self, other):
if isinstance(other, Person):
self.members.append(other)
return self
elif isinstance(other, Team):
self.members.extend(other.members)
return self
else:
raise TypeError("Can't add {!r} to the team.".format(other))


utilizzo
# creiamo 4 istanze di Person
guido = Person('Guido', 'van Rossum')
tim = Person('Tim', 'Peters')
alex = Person('Alex', 'Martelli')
ezio = Person('Ezio', 'Melotti')


# creiamo 2 team da 2 persone per team
t1 = Team([guido, tim])
t2 = Team([alex, ezio])


# verifichiamo i membri dei 2 team
t1
<Team object [Guido, Tim]>

t2
<Team object [Alex, Ezio]>


# verifichiamo l'overloading dell'operatore in
guido in t1
True

ezio in t1
False

ezio not in t1
True


# verifichiamo l'overloading dell'operatore + (__add__)
# sommando un'istanza di Team con una di Person
t1 + ezio
<Team object [Guido, Tim, Ezio]>


# verifichiamo che l'operazione ha restituito
# un nuovo team, e che t1 non è cambiato
t1
<Team object [Guido, Tim]>


# verifichiamo l'overloading dell'operatore + (__radd__)
# sommando un'istanza di Person con una di Team
ezio + t1
<Team object [Guido, Tim, Ezio]>


# verifichiamo l'overloading dell'operatore + (__add__)
# sommando due istanze di Team
t1 + t2
<Team object [Guido, Tim, Alex, Ezio]>

t2 + t1
<Team object [Alex, Ezio, Guido, Tim]>


# verifichiamo che t1 contiene 2 membri
t1
<Team object [Guido, Tim]>


# verifichiamo l'overloading dell'operatore += (__iadd__)
# aggiungendo un'istanza di Person al Team t1
1 += ezio


# verifichiamo che t1 è stato modificato
t1
<Team object [Guido, Tim, Ezio]>


# creiamo altre 2 istanze di Team
t3 = Team([alex, tim])
t4 = Team([guido, ezio])


# verifichiamo che t3 contiene 2 membri
t3
<Team object [Alex, Tim]>


# verifichiamo l'overloading dell'operatore += (__iadd__)
# aggiungendo un'istanza di Team al Team t3
t3 += t4


# verifichiamo che t3 è stato modificato
t3
<Team object [Alex, Tim, Guido, Ezio]>


# verifichiamo che aggiungere un tipo incompatibile
# ci restituisce un TypeError
t3 + 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 15, in __add__
TypeError: Can't add Team with 5.



tabelle con operatori e meotodi relativi

operatori aritmetici
OperatoreDescrizioneMetodi speciali
+addizione__add__, __radd__, __iadd__
sottrazione__sub__, __rsub__, __isub__
*moltiplicazione__mul__, __rmul__, __imul__
/divisione__truediv__, __rtruediv__, __itruediv__
//divisione intera__floordiv__, __rfloordiv__, __ifloordiv__
%modulo (resto della divisione)__mod__, __rmod__, __imod__


operatore di confronto
OperatoreDescrizioneMetodo speciali
==uguale a__eq__
!=diverso da__ne__
<minore di__lt__
<=minore o uguale a__le__
>maggiore di__gt__
>=maggiore o uguale a__ge__


operatori binari
OperatoreDescrizioneMetodi speciali
x << nesegue uno shift a sinistra di n posizioni dei bit di x__lshift__, __rlshift__, __ilshift__
x >> nesegue uno shift a destra di n posizioni dei bit di x__rshift__, __rrshift__, __irshift__
x & yesegue un and tra i bit di x e di y__and__, __rand__, __iand__
x | yesegue un or tra i bit di x e di y__or__, __ror__, __ior__
x ^ yesegue un or esclusivo tra i bit di x e di y__xor__, __rxor__, __ixor__


accesso, l'assegnamento, e la rimozione di elementi o attributi
OperatoreDescrizioneMetodo speciali
object[item]accesso a un elemento__getitem__
object[item] = valueassegnamento a un elemento__setitem__
del object[item]rimozione di un elemento__delitem__
object.attraccesso a un attributo__getattr__
object.attr = valueassegnamento a un attributo__setattr__
del object.attrrimozione di un attributo__delattr__