Diferència entre revisions de la pàgina «POO Operadors»
 (Es crea la pàgina amb «Els operadors ens permeten operacions matemàtiques i lògiques. Els més coneguts serien: * Aritmètics: + , - , * , / * Lògics: and , or , not , xor * Comparacions: > …».)  | 
				|||
| (Hi ha 9 revisions intermèdies del mateix usuari que no es mostren) | |||
| Línia 5: | Línia 5: | ||
* Matemàtics: ''mod'' o % (resta divisió entera) , ...  | * Matemàtics: ''mod'' o % (resta divisió entera) , ...  | ||
| + | Podeu llegir una referència més detallada del [http://docs.python.org/reference/datamodel.html 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.  | 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"  | + | Teniu altres exemples d'utilització d'operadors en [[POO operadors 2]].  | 
| + | |||
| + | <br>  | ||
| + | |||
| + | == Exemple amb classes Python ==  | ||
| + | Per exemple, prenem el cas de la classe "Pilota".  | ||
<syntaxhighlight lang="python">  | <syntaxhighlight lang="python">  | ||
| Línia 48: | Línia 54: | ||
* No igualtat (!=): '''__ne__''' (not equal)  | * No igualtat (!=): '''__ne__''' (not equal)  | ||
| − | La distància a l'origen es defineix per sqrt(posx  | + | 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*self.posy > 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*self.posy < 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*self.posy == other.posx*other.posy  | + | 	   return self.posx**2+self.posy**2 == other.posx**2+other.posy**2  | 
</syntaxhighlight>  | </syntaxhighlight>  | ||
| Línia 68: | Línia 77: | ||
  >>> a > b  |   >>> a > b  | ||
  False  |   False  | ||
| + |  >>>   | ||
  >>> a.posx = 100  |   >>> a.posx = 100  | ||
| − | |||
  >>> a == b  |   >>> a == b  | ||
  False  |   False  | ||
  >>> a > b  |   >>> a > b  | ||
  True  |   True  | ||
| − | |||
== Ordenant llistes ==  | == Ordenant llistes ==  | ||
| Línia 95: | Línia 103: | ||
  >>> c  |   >>> c  | ||
  [(10,10), (100,100), (50,10), (1,1)]  |   [(10,10), (100,100), (50,10), (1,1)]  | ||
| − |   >>> c  | + |   >>> sorted(c)  | 
| − | |||
  [(1,1), (10,10), (50,10), (100,100)]  |   [(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í:  | ||
| + | |||
| + | <syntaxhighlight lang="python">  | ||
| + |    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)  | ||
| + | </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)