Classes & objets

Définition

Méthodes

Constructeur, attributs

Debug

String casting

Opérateurs

Documentation

Comme pour les fonctions, la documentation d’une classe et de ses méthodes doit être placée directement après la ligne d’instanciation. La méthode help permet d’afficher la documentation d’une classe.

class Point:
  """
  Classe pour représenter un point dans le plan
  """

  def __init__(self,x,y):
    """
    Creation d'un nouveau point de position (x,y)
    """
    self.x = x
    self.y = y

  def translate(self, dx, dy):
    """
    Ajoute (dx,dy) à (x,y)
    """
    self.x += dx
    self.y += dy

  def __str__(self):
    return "Point: [%f, %f]" % (self.x, self.y)

help(Point)

Méthodes de classe


Héritage

Mangling

Getter et setter

Vérifier une instance de classe

class Base(object):  pass
class Derived(Base): pass

print(issubclass(Derived, Base)) # True

objDerived = Derived() 
print(isinstance(objDerived, Derived)) # True
print(isinstance(objDerived, Base))    # True

Méthodes magiques

Call

La méthode __call__ est invoquée quand on utilise une instance de classe comme une fonction

class Test:
    def __init__(self, name):
      self.name = name

    def __call__(self):
      print("Hello " + self.name)

obj = Test("Bob")
obj() # Hello Bob

Destructeur

La méthode magique __del__ est appelée quand toute les références vers l’objet ont été supprimées (l’objet va être libéré de la mémoire par le garbage collector).

class Test:
    def __init__(self):
        print('Constructor called')

    def __del__(self):
        print('Destructor called')

obj = Test() # Constructor called
del obj      # Destructor called

Si l’objet n’est jamais supprimé, le destructeur sera appelé après la fin du programme.

obj = Test()             # Constructor called
print('Program End...')  # Program End
                         # Destructor called

Itérateurs

Les listes, tuples, dictionnaires et sets sont des objets itérables (on peut utiliser la fonction for dessus). On peut également les convertir en itérateurs avec la fonction iter:

l  = [1,2,3]
it = iter(l)

print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
print(next(it)) # StopIteration error

Pour obtenir ce même comportement avec un objet, il faut implémenter les méthodes magiques __iter__ et __next__

class MyRange:
    def __init__(self, _from, _to=None, _step=1):
        if _to==None:
            self._to   = _from
            self._from = 0 
        else:
            self._from = _from
            self._to   = _to

        self._step = _step if _step != 0 else 1

    def __iter__(self):
        self.i = self._from
        return self

    def __next__(self):
        if self._step > 0:
            if self.i >= self._to: raise StopIteration
        elif self.i <= self._to:
            raise StopIteration

        i = self.i
        self.i += self._step
        return i
obj = MyRange(5)

for i in obj:
    print(i)
# 0 1 2 3 4
obj = MyRange(1,4)
it  = iter(obj)

print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
print(next(it)) # StopIteration error

Opérateurs

Quand on utilise l’opérateur + sur un objet, la méthode magique __add__ est invoquée. Cette méthode peut retourner n’importe quel type de donnée — une instance de classe, un entier, etc.

class Test:
    def __init__(self, n):
        self.n = n

    def __add__(self, obj):
        return Test(self.n + obj.n)

obj1 = Test(1)
obj2 = Test(2)
obj3 = obj1 + obj2

print(obj3.n) # 3

Il existe tout un tas de méthodes magiques permettant de surcharger le résultat des opérateurs:

Opérateur Méthode magique
+ __add__(self, other)
- __sub__(self, other)
* __mul__(self, other)
/ __truediv__(self, other)
// __floordiv__(self, other)
% __mod__(self, other)
** __pow__(self, other)
   
-= __isub__(self, other)
+= __iadd__(self, other)
*= __imul__(self, other)
/= __idiv__(self, other)
//= __ifloordiv__(self, other)
%= __imod__(self, other)
**= __ipow__(self, other)
   
- (unaire) __neg__(self)
+ (unaire) __pos__(self)
~ (unaire) __invert__(self)
   
< __lt__(self, other)
> __gt__(self, other)
<= __le__(self, other)
>= __ge__(self, other)
== __eq__(self, other)
!= __ne__(self, other)

Enter

Metaclass