======== Com ...? ======== Com definir una classe? ----------------------- >>> class Cercle: ... pass Com instanciar objectes de la nova classe? ------------------------------------------ >>> c1 = Cercle() >>> type(c1) >>> 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) # doctest: +ELLIPSIS ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', ...] >>> str(c1) # doctest: +ELLIPSIS '<__main__.Cercle object at ...>' >>> repr(c1) # doctest: +ELLIPSIS '<__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) - Vegeu :ref:`metode_init`. 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 - Vegeu-ho al `Python Tutor`__ __ http://pythontutor.com/live.html#code=from%20math%20import%20pi%0A%0Aclass%20Cercle%3A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20radi%29%3A%0A%20%20%20%20%20%20%20%20self.x%20%3D%20x%0A%20%20%20%20%20%20%20%20self.y%20%3D%20y%0A%20%20%20%20%20%20%20%20self.r%20%3D%20radi%0A%20%20%20%20def%20area%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20pi%20*%20self.r**2%0A%20%20%20%20def%20__eq__%28self,%20c%29%3A%0A%20%20%20%20%20%20%20%20return%20%28self.x,%20self.y,%20self.r%29%20%3D%3D%20%28c.x,%20c.y,%20c.r%29%0A%0Ac5%20%3D%20Cercle%283,%20-2,%205%29%0Ac6%20%3D%20Cercle%283,%20-2,%205%29%0Aprint%28c5%20%3D%3D%20c6%29%0Aprint%28c5%20is%20c6%29%0Ac6.y%20%3D%204%0Aprint%28c5%20%3D%3D%20c6%29%0A&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false - Vegeu :ref:`sobrecarrega_operadors`. Com fer còpies idèntiques d'objectes? ------------------------------------- - Moltes classes ofereixen un mètode :py:meth:`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 :py:mod:`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 __ http://pythontutor.com/live.html#code=import%20copy%0A%0Al%20%3D%20%5B1,%20%5B2,%203,%204%5D%5D%0Am%20%3D%20copy.copy%28l%29%0An%20%3D%20copy.deepcopy%28l%29&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false - Vegeu :ref:`copia`. 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`__ __ http://pythontutor.com/visualize.html#code=from%20math%20import%20pi%0A%0Aclass%20Cercle%3A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20radi%29%3A%0A%20%20%20%20%20%20%20%20self.x%20%3D%20x%0A%20%20%20%20%20%20%20%20self.y%20%3D%20y%0A%20%20%20%20%20%20%20%20self.r%20%3D%20radi%0A%20%20%20%20def%20area%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20pi%20*%20self.r**2%0A%20%20%20%20def%20__eq__%28self,%20c%29%3A%0A%20%20%20%20%20%20%20%20return%20%28self.x,%20self.y,%20self.r%29%20%3D%3D%20%28c.x,%20c.y,%20c.r%29%0A%0Aclass%20SectorCircular%28Cercle%29%3A%0A%20%20%20%20pass%0A%0As1%20%3D%20SectorCircular%283,%20-2,%205%29%0Aprint%28s1.x,%20s1.y,%20s1.r%29%0Aprint%28s1.area%28%29%29%0A&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false Com afegir atributs als objectes d'una classe derivada? ------------------------------------------------------- - Cal redefinir el mètode :py:meth:`~object.__init__`. - Cal cridar el mètode :py:meth:`~object.__init__` de la classe pare. >>> 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) - Vegeu-ho al `Python Tutor`__ __ http://pythontutor.com/visualize.html#code=from%20math%20import%20pi%0A%0Aclass%20Cercle%3A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20radi%29%3A%0A%20%20%20%20%20%20%20%20self.x%20%3D%20x%0A%20%20%20%20%20%20%20%20self.y%20%3D%20y%0A%20%20%20%20%20%20%20%20self.r%20%3D%20radi%0A%20%20%20%20def%20area%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20pi%20*%20self.r**2%0A%20%20%20%20def%20__eq__%28self,%20c%29%3A%0A%20%20%20%20%20%20%20%20return%20%28self.x,%20self.y,%20self.r%29%20%3D%3D%20%28c.x,%20c.y,%20c.r%29%0A%0Aclass%20SectorCircular%28Cercle%29%3A%0A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20r%29%3A%0A%20%20%20%20%20%20%20%20%23%20Cercle.__init__%28self,%20x,%20y,%20r%29%0A%20%20%20%20%20%20%20%20%23%20super%28SectorCircular,%20self%29.__init__%28x,%20y,%20r%29%0A%20%20%20%20%20%20%20%20super%28%29.__init__%28x,%20y,%20r%29%0A%20%20%20%20%20%20%20%20self.angle%20%3D%200%0A%0As2%20%3D%20SectorCircular%283,%20-2,%205%29%0Aprint%28s2.x,%20s2.y,%20s2.r,%20s2.angle%29%0A&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false 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 :py:meth:`~object.__init__` de la classe derivada pot tenir un nombre diferent de paràmetres amb un significat diferent. - Vegeu-ho al `Python Tutor`__ __ http://pythontutor.com/visualize.html#code=from%20math%20import%20pi%0A%0Aclass%20Cercle%3A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20radi%29%3A%0A%20%20%20%20%20%20%20%20self.x%20%3D%20x%0A%20%20%20%20%20%20%20%20self.y%20%3D%20y%0A%20%20%20%20%20%20%20%20self.r%20%3D%20radi%0A%20%20%20%20def%20area%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20pi%20*%20self.r**2%0A%20%20%20%20def%20__eq__%28self,%20c%29%3A%0A%20%20%20%20%20%20%20%20return%20%28self.x,%20self.y,%20self.r%29%20%3D%3D%20%28c.x,%20c.y,%20c.r%29%0A%0Aclass%20SectorCircular%28Cercle%29%3A%0A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20r,%20a%29%3A%0A%20%20%20%20%20%20%20%20super%28%29.__init__%28x,%20y,%20r%29%0A%20%20%20%20%20%20%20%20self.angle%20%3D%20a%0A%0As3%20%3D%20SectorCircular%283,%20-2,%205,%201.2%29%0Aprint%28s3.x,%20s3.y,%20s3.r,%20s3.angle%29%0A&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false 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 - Vegeu-ho al `Python Tutor`__ __ http://pythontutor.com/visualize.html#code=from%20math%20import%20pi%0A%0Aclass%20Cercle%3A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20radi%29%3A%0A%20%20%20%20%20%20%20%20self.x%20%3D%20x%0A%20%20%20%20%20%20%20%20self.y%20%3D%20y%0A%20%20%20%20%20%20%20%20self.r%20%3D%20radi%0A%20%20%20%20def%20area%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20pi%20*%20self.r**2%0A%20%20%20%20def%20__eq__%28self,%20c%29%3A%0A%20%20%20%20%20%20%20%20return%20%28self.x,%20self.y,%20self.r%29%20%3D%3D%20%28c.x,%20c.y,%20c.r%29%0A%0Aclass%20SectorCircular%28Cercle%29%3A%0A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20r,%20a%29%3A%0A%20%20%20%20%20%20%20%20super%28%29.__init__%28x,%20y,%20r%29%0A%20%20%20%20%20%20%20%20self.angle%20%3D%20a%0A%0A%20%20%20%20def%20area%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20self.r%20**%202%20*%20self.angle%20/%202.0%0A%0As4%20%3D%20SectorCircular%283,%20-2,%205,%201.2%29%0Aprint%28s4.area%28%29%29%0A&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false 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 - Vegeu-ho al `Python Tutor`__ __ http://pythontutor.com/visualize.html#code=from%20math%20import%20pi%0A%0Aclass%20Cercle%3A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20radi%29%3A%0A%20%20%20%20%20%20%20%20self.x%20%3D%20x%0A%20%20%20%20%20%20%20%20self.y%20%3D%20y%0A%20%20%20%20%20%20%20%20self.r%20%3D%20radi%0A%20%20%20%20def%20area%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20pi%20*%20self.r**2%0A%20%20%20%20def%20__eq__%28self,%20c%29%3A%0A%20%20%20%20%20%20%20%20return%20%28self.x,%20self.y,%20self.r%29%20%3D%3D%20%28c.x,%20c.y,%20c.r%29%0A%0Aclass%20SectorCircular%28Cercle%29%3A%0A%0A%20%20%20%20def%20__init__%28self,%20x,%20y,%20r,%20a%29%3A%0A%20%20%20%20%20%20%20%20super%28%29.__init__%28x,%20y,%20r%29%0A%20%20%20%20%20%20%20%20self.angle%20%3D%20a%0A%0A%20%20%20%20def%20area%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20self.r%20**%202%20*%20self.angle%20/%202.0%0A%0A%20%20%20%20def%20long_arc%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20self.r%20*%20self.angle%0A%0As5%20%3D%20SectorCircular%283,%20-2,%205,%201.2%29%0Aprint%28s5.long_arc%28%29%29%0A&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false