POO Operadors

De Cacauet Wiki
Salta a la navegació Salta a la cerca

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) , ...


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.

Per exemple, prenem el cas de la classe "Pilota". Per saber si una pilota "a" és més gran que una "b", es podria tenir diversos criteris. Si no els definim, en principi no les podem comparar.

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(posx*posy) . 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*self.posy > other.posx*other.posy
   def __lt__(self, other):
	   return self.posx*self.posy < other.posx*other.posy
   def __eq__(self, other):
	   return self.posx*self.posy == 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.