Diferència entre revisions de la pàgina «POO Operadors»
| (Hi ha 3 revisions intermèdies del mateix usuari que no es mostren) | |||
| Línia 8: | Línia 8: | ||
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.  | 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.  | ||
| + | |||
| + | Teniu altres exemples d'utilització d'operadors en [[POO operadors 2]].  | ||
| + | |||
| + | <br>  | ||
== Exemple amb classes Python ==  | == Exemple amb classes Python ==  | ||
| Línia 50: | Línia 54: | ||
* 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(posx<sup>2</sup>+posy<sup>2</sup>)  | ||
| + | Però a efectes de comparació en tenim prou en comparar els quadrats (si a>b, també es compleix a<sup>2</sup>>b<sup>2</sup>). Per tant, podem comparar:  | ||
| + |  posx<sup>2</sup>+posy<sup>2</sup>  | ||
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**2+self.posy**2 > other.posx*other.posy  | + | 	   return self.posx**2+self.posy**2 > other.posx**2+other.posy**2  | 
    def __lt__(self, other):  |     def __lt__(self, other):  | ||
| − | 	   return self.posx**2+self.posy**2 < other.posx*other.posy  | + | 	   return self.posx**2+self.posy**2 < other.posx**2+other.posy**2  | 
    def __eq__(self, other):  |     def __eq__(self, other):  | ||
| − | 	   return self.posx**2+self.posy**2 == other.posx*other.posy  | + | 	   return self.posx**2+self.posy**2 == other.posx**2+other.posy**2  | 
</syntaxhighlight>  | </syntaxhighlight>  | ||
| Línia 124: | Línia 131: | ||
    def __eq__(self, other):  |     def __eq__(self, other):  | ||
       if type(other)==Pilota:  |        if type(other)==Pilota:  | ||
| − |           return self.posx*self.posy == other.posx*other.posy  | + |           return self.posx**2+self.posy**2 == other.posx**2+other.posy**2  | 
       elif type(other)==int:  |        elif type(other)==int:  | ||
| − |           return other == sqrt(self.posx*self.posy)  | + |           return other == sqrt(self.posx**2+self.posy**2)  | 
</syntaxhighlight>  | </syntaxhighlight>  | ||
Revisió de 22:04, 31 oct 2013
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.
Teniu altres exemples d'utilització d'operadors en POO operadors 2.
Contingut
Exemple amb classes Python[modifica]
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[modifica]
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 els quadrats (si a>b, també es compleix a2>b2). Per tant, podem comparar:
posx2+posy2
Definim els operadors bàsics: >, < i ==
   def __gt__(self, other):
	   return self.posx**2+self.posy**2 > other.posx**2+other.posy**2
   def __lt__(self, other):
	   return self.posx**2+self.posy**2 < other.posx**2+other.posy**2
   def __eq__(self, other):
	   return self.posx**2+self.posy**2 == other.posx**2+other.posy**2
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[modifica]
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[modifica]
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**2+self.posy**2 == other.posx**2+other.posy**2
      elif type(other)==int:
         return other == sqrt(self.posx**2+self.posy**2)