Definició de classes

Per què cal definir classes?

  • Els tipus predefinits resulten incòmodes: Nutrició, Perfums, …

    Sense classes

    >>> al1 = ('Cigrons',18,5,61)
    >>> nom1 = al1[0]
    >>> proteines1 = al1[1]
    >>> lipids1 = al1[2]
    >>> carbohidrats1 = al1[3]
    

    Amb classes

    >>> al1 = Aliment('Cigrons',18,5,61)
    >>> nom1 = al1.nom
    >>> proteines1 = al1.proteïnes
    >>> lipids1 = al1.lípids
    >>> carbohidrats1 = al1.carbohidrats
    
  • Volem agrupar dades i operacions: Classe Punt2D, Polinomi, …

  • Tenim tipus molt semblants i volem reaprofitar codi: Cercle i SectorCircular en el mòdul figures, …

Què és una classe?

  • Una classe és una plantilla a partir de la qual es poden crear (instanciar) objectes.

  • Direm que l’objecte o és una instància de la classe C si el tipus d”o és C. Per exemple:

    • 3 és una instància de la classe int perquè

      >>> type(3) == int
      True
      >>> isinstance(3, int)
      True
      
    • [3, 'a'] és una instància de la classe list perquè

      >>> type([3, 'a']) == list
      True
      >>> isinstance([3, 'a'])
      True
      
  • Normalment les definicions de classes contenen definicions de mètodes que operen sobre instàncies de la classe.

Sentència class

class Nom:
    sentències
  • Defineix un nou espai de noms.

  • Atributs: noms que es creen en executar les sentències.

    • Atributs de dades: atributs creats per assignacions. Són atributs de la classe.

    • Mètodes: atributs creats per la definició de funcions.

      • Tenen un paràmetre com a mínim: self.

  • Crea un nou objecte (de tipus type).

>>> class A:
...   a1 = 3
...   def m1(self):
...     return self.a1 + 1
...
>>> dir()
['A', ..., '__name__', ...]
>>> dir(A)
['__class__', ..., '__init__', ..., 'a1', 'm1']
>>> type(A)
<class 'type'>

Operacions de les classes

  • Les classes (objectes de tipus type) tenen dues operacions:

    • Referència a un atribut.

    • Instanciació: retorna una instància de la classe.

Referència a un atribut

  • Sintaxi:

    objecte.atribut
    
  • Exemples:

    >>> A.a1
    3
    >>> A.m1
    <function m1 at 0x7feb171f55a0>
    

Referència a un atribut al Python Tutor

Instanciació

  • Sintaxi de crida a funció:

    io = Nom()
    
  • Crea una instància de la classe amb els atributs de la classe Nom.

  • Immediatament abans de retornar la instància crida al mètode especial __init__().

>>> a = A()
>>> type(a)
<class '__main__.A'>
>>> dir()
['A', ..., 'a']
>>> dir(a)
['__class__', ..., '__str__', ..., 'a1', 'm1']
>>> a.a1 # referència a un atribut
3
>>> a.m1() # crida a un mètode
4

Instanciació d’una classe al Python Tutor

El mètode __init__()

  • El mètode __init__() no retorna res (retorna None). S’usa per inicialitzar els atributs de dades de la instància. Són atributs de la instància.

  • El mètode __init__() pot tenir paràmetres. Aleshores l’operació d’instanciació ha de proporcionar el arguments.

>>> class A:
...   a1 = 3
...   def __init__(self, x):
...     self.a2 = x
...   def m1(self):
...     return self.a1 + self.a2
...
>>> a = A(-8)
>>> dir(a)
['__class__', ..., 'a1', 'a2', 'm1']

El mètode __init__() al Python Tutor

(Paràmetres opcionals)

  • Sintaxi dels paràmetres de les funcions:

    def f(p, o1=3, o2="abc"):
        return "{2}: {0}, {1}".format(p, o1, o2)
    
  • Exemples de crides:

    >>> f(-2)
    'abc: -2, 3'
    >>> f(-2, 5)
    'abc: -2, 5'
    >>> f(-2, 5, 'xyz')
    'xyz: -2, 5'
    >>> f(-2, o2='rst')
    'rst: -2, 3'
    

Paràmetres opcionals al Python Tutor

Perill

No poseu objectes mutables com a valor per defecte.

Vegeu Why are default values shared between objects? a les Programming FAQ

__init__() amb paràmetres opcionals

>>> class A:
...   a1 = 3
...   def __init__(self, x=0):
...     self.a2 = x
...   def m1(self):
...     return self.a1 + self.a2
...
>>> a = A(-8)
>>> dir(a)
['__class__', ..., 'a1', 'a2', 'm1']
>>> b = A()
>>> dir(b)
['__class__', ..., 'a1', 'a2', 'm1']

El mètode __init__() amb paràmetres opcionals al Python Tutor

Instàncies

  • L’objecte o és una instància de la classe C si el tipus d”o és C.

  • Només tenen l’operació de referència a un atribut.

  • L’atribut pot ser un atribut de dades o un mètode.

  • Podem consultar i modificar els valors dels atributs de dades de la instància.

  • Podem cridar els mètodes de la instància.

>>> a.a1, a.a2, a.m1()
(3, -8, -5)
>>> b.a1, b.a2, b.m1()
(3, 0, 3)

Instàncies al Python Tutor

Sobrecàrrega d’operadors

Polimorfisme

  • Funcions que poden ser cridades amb paràmetres de tipus diferents.

  • La sobrecàrrega d’operadors és polimorfisme.

  • Exemples: operadors, mòdul figures.

Còpia d’objectes

Exercicis

Disseny de classes sense mètodes especials (llevat de __str__)

Disseny de classes amb mètodes especials