Com …?

Com definir una classe?

>>> class Cercle:
...     pass

Com instanciar objectes de la nova classe?

>>> c1 = Cercle()
>>> type(c1)
<class '__main__.Cercle'>
>>> isinstance(c1, Cercle)
True
  • Direm que c1 és un objecte o una instància de classe Cercle.

Quins atributs (i mètodes) té c1?

  • Els mateixos que la classe Cercle.

>>> dir(c1)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', ...]
>>> str(c1)
'<__main__.Cercle object at ...>'
>>> repr(c1)
'<__main__.Cercle object at ...>'
>>> c2 = Cercle()
>>> c1 == c2
False
>>> c1 is c2
False

Com afegir atributs a totes les instàncies de la classe?

  • Cal redefinir el mètode __init__.

>>> class Cercle:
...     def __init__(self):
...         self.x = 0
...         self.y = 0
...         self.r = 1
>>> c3 = Cercle()
>>> c3.x
0
>>> c3.x = 7
>>> c3.x
7

Com fer que els atributs tinguin valors diferents en cada instància?

  • Cal afegir paràmetres al mètode __init__.

>>> class Cercle:
...     def __init__(self, x, y, radi):
...         self.x = x
...         self.y = y
...         self.r = radi
>>> c4 = Cercle(3, -2, 5)
>>> c4.x, c4.y, c4.r
(3, -2, 5)

Com afegir mètodes?

>>> from math import pi
>>> class Cercle:
...     def __init__(self, x, y, radi):
...         self.x = x
...         self.y = y
...         self.r = radi
...     def area(self):
...         return pi * self.r**2
>>> c4 = Cercle(3, -2, 5)
>>> round(c4.area(), 5)
78.53982

Com afegir operadors?

>>> from math import pi
>>> class Cercle:
...     def __init__(self, x, y, radi):
...         self.x = x
...         self.y = y
...         self.r = radi
...     def area(self):
...         return pi * self.r**2
...     def __eq__(self, c):
...         return (self.x, self.y, self.r) == (c.x, c.y, c.r)
>>> c5 = Cercle(3, -2, 5)
>>> c6 = Cercle(3, -2, 5)
>>> c5 == c6
True
>>> c5 is c6
False
>>> c6.y = 4
>>> c5 == c6
False

Com fer còpies idèntiques d’objectes?

  • Moltes classes ofereixen un mètode copy().

    >>> l = [1, 2]
    >>> m = l.copy()
    >>> l == m
    True
    >>> l is m
    False
    
    >>> d = {'a': 3, 'b': 4}
    >>> e = d.copy()
    >>> d == e
    True
    >>> d is e
    False
    
  • El mòdul copy ajuda a fer còpies idèntiques d’objectes.

    >>> import copy
    
    >>> l = [1, [2, 3, 4]]
    >>> m = copy.copy(l)
    >>> l == m
    True
    >>> l is m
    False
    >>> l[1] is m[1]
    True
    
    >>> n = copy.deepcopy(l)
    >>> l == n
    True
    >>> l is n
    False
    >>> l[1] is n[1]
    False
    

Com derivar per herència una classe?

>>> class SectorCircular(Cercle):
...     pass
>>> s1 = SectorCircular(3, -2, 5)
>>> s1.x, s1.y, s1.r
(3, -2, 5)
>>> round(s1.area(), 2)
78.54
  • La classe derivada (o filla) hereta tots els mètodes (i atributs) de la classe base (o pare).

  • Vegeu-ho al Python Tutor

Com afegir atributs als objectes d’una classe derivada?

>>> class SectorCircular(Cercle):
...
...     def __init__(self, x, y, r):
...         # Cercle.__init__(self, x, y, r)
...         # super(SectorCircular, self).__init__(x, y, r)
...         super().__init__(x, y, r)
...         self.angle = 0
>>> s2 = SectorCircular(3, -2, 5)
>>> s2.x, s2.y, s2.r, s2.angle
(3, -2, 5, 0)

Com fer que els atributs tinguin valors diferents en cada instància d’una classe derivada?

>>> class SectorCircular(Cercle):
...
...     def __init__(self, x, y, r, a):
...         super().__init__(x, y, r)
...         self.angle = a
>>> s3 = SectorCircular(3, -2, 5, 1.2)
>>> s3.x, s3.y, s3.r, s3.angle
(3, -2, 5, 1.2)
  • El mètode __init__() de la classe derivada pot tenir un nombre diferent de paràmetres amb un significat diferent.

  • Vegeu-ho al Python Tutor

Com redefinir mètodes en una classe derivada?

>>> class SectorCircular(Cercle):
...
...     def __init__(self, x, y, r, a):
...         super().__init__(x, y, r)
...         self.angle = a
...
...     def area(self):
...         return self.r ** 2 * self.angle / 2.0
>>> s4 = SectorCircular(3, -2, 5, 1.2)
>>> s4.area()
15.0

Com afegir mètodes a una classe derivada?

>>> class SectorCircular(Cercle):
...
...     def __init__(self, x, y, r, a):
...         super().__init__(x, y, r)
...         self.angle = a
...
...     def area(self):
...         return self.r ** 2 * self.angle / 2.0
...
...     def long_arc(self):
...         return self.r * self.angle
>>> s5 = SectorCircular(3, -2, 5, 1.2)
>>> s5.long_arc()
6.0