Diferència entre revisions de la pàgina «POO Operadors»
Línia 50: | Línia 50: | ||
* No igualtat (!=): '''__ne__''' (not equal) | * No igualtat (!=): '''__ne__''' (not equal) | ||
− | La distància a l'origen es defineix per sqrt( | + | La distància a l'origen es defineix per sqrt(posx2*posy2) . Però a efectes de comparació en tenim prou en comparar posx*posy dels dos elements. |
Definim els operadors bàsics: >, < i == | Definim els operadors bàsics: >, < i == | ||
<syntaxhighlight lang="python"> | <syntaxhighlight lang="python"> | ||
def __gt__(self, other): | def __gt__(self, other): | ||
− | return self.posx*self.posy > other.posx*other.posy | + | return self.posx**2+self.posy**2 > other.posx*other.posy |
def __lt__(self, other): | def __lt__(self, other): | ||
− | return self.posx*self.posy < other.posx*other.posy | + | return self.posx**2+self.posy**2 < other.posx*other.posy |
def __eq__(self, other): | def __eq__(self, other): | ||
− | return self.posx*self.posy == other.posx*other.posy | + | return self.posx**2+self.posy**2 == other.posx*other.posy |
</syntaxhighlight> | </syntaxhighlight> | ||
Revisió del 16:13, 15 nov 2012
Els operadors ens permeten operacions matemàtiques i lògiques. Els més coneguts serien:
- Aritmètics: + , - , * , /
- Lògics: and , or , not , xor
- Comparacions: > , >= , < , <= , == , !=
- Matemàtics: mod o % (resta divisió entera) , ...
Podeu llegir una referència més detallada del model de dades de Python.
Els més utilitzats son els operadors de comparació. Amb aquests podem definir comportaments dels objectes que definim a l'hora, per exemple, de fer ordenacions (sort) de llistes d'objectes.
Contingut
Exemple amb classes Python
Per exemple, prenem el cas de la classe "Pilota".
class Pilota(object):
# atributs
velocitat = 10
posx = 10
posy = 12
# mètodes
def __init__(self, x=10, y=12):
self.posx = x
self.posy = y
def accelera(self):
self.velocitat = self.velocitat + 5
def posicio(self,x,y):
self.posx = x
self.posy = y
Si intentem comparar 2 instàncies sense definir res, ho farà en virtut de la seva adreça de memòria, cosa que en principi no ens resulta útil per a res:
>>> a = Pilota() >>> b = Pilota() >>> id(a) 3073101612L >>> id(b) 3073101580L >>> a > b True
Redefinint operadors
Redefinirem els operadors: > , < i == . Utilitzarem el criteri de distància a l'origen (podria ser un altre criteri, com el tamany).
Es poden definir les següents funcions:
- Major que (>): __gt__ (greater than)
- Major igual (>=): __ge__ (greater equal)
- Menor que (<): __lt__ (less than)
- Menor igual (<=): __le__ (less equal)
- Igualtat (==): __eq__ (equal)
- No igualtat (!=): __ne__ (not equal)
La distància a l'origen es defineix per sqrt(posx2*posy2) . Però a efectes de comparació en tenim prou en comparar posx*posy dels dos elements.
Definim els operadors bàsics: >, < i ==
def __gt__(self, other):
return self.posx**2+self.posy**2 > other.posx*other.posy
def __lt__(self, other):
return self.posx**2+self.posy**2 < other.posx*other.posy
def __eq__(self, other):
return self.posx**2+self.posy**2 == other.posx*other.posy
Com podeu veure, els operadors necessiten 2 paràmetres: self i other. Un és l'objecte mateix i l'altre el que se li compara. Per veure que funciona farem:
>>> a = Pilota() >>> b = Pilota() >>> a == b True >>> a > b False >>> >>> a.posx = 100 >>> a == b False >>> a > b True
Ordenant llistes
Mercès a aquests operadors, ara podem ordenar un array de Pilotes. Per poder-ho comprovar, podem canviar la representació d'una pilota (quan fem un "print" o mostrem l'array):
def __repr__(self):
return "(%d,%d)"%(self.posx,self.posy)
Ara podem veure les coordenades més fàcilment:
>>> a = Pilota() >>> a (10,12) >>> print a (10,12)
Fem un array i l'ordenem:
>>> c = [ Pilota(10,10) , Pilota(100,100) , Pilota(50,10) , Pilota(1,1) ] >>> c [(10,10), (100,100), (50,10), (1,1)] >>> sorted(c) [(1,1), (10,10), (50,10), (100,100)]
També tenim el mètode .sort() però aquest modifica permanentment l'ordre de la llista.
NOTA: de fet, per poder ordenar una llista, només és necessari implementar un dels dos operadors: > o bé < . Les funcions de Python ja s'encarreguen d'utilitzar el mètode que hem implementat per la classe.
Comparant diferents tipus de dades
Si comparem una Pilota amb un integer veurem que ens dona un error:
>>> a = 10 >>> b = Pilota() >>> a==b Traceback (most recent call last): File "<stdin>", line 1, in <module> File "operadors.py", line 24, in __eq__ return self.posx*self.posy == other.posx*other.posy AttributeError: 'int' object has no attribute 'posx'
Si ens fixem bé veurem que és perquè el nostre mètode de comparació accedeix a un atribut "posx" que un int no té.
Si volem comparar 2 tipus de dades diferents caldrà implementar la selecció de tipus dins de l'operador de comparació.
...TODO... algo així:
def __eq__(self, other):
if type(other)==Pilota:
return self.posx*self.posy == other.posx*other.posy
elif type(other)==int:
return other == sqrt(self.posx*self.posy)