Objets et références en Python

Les exercices ci-dessous sont réalisés dans l’interpréteur REPL. Tapez les commandes et expliquez les résultats.

Références

  • Représenter les objets et références ci-dessous en mémoire:
pi = 3.14
salut = 'Bonjour'
d = {'Bordeaux': 33, 'Nantes': 44, 'Toulouse': 31}
  • Représenter l’effet des opérations ci-dessous en mémoire:
p = 2 * pi
pi = 0
d['Marseille'] = 13
  • Expliquer l’effet des opérations ci-dessous:
salut[0] = 'b'
d = {'Lille': 59}
  • Dans la déclaration de l ci-dessous, que fait [0]? Que fait [0] * 4? Que fait [[0] * 4] * 3? Dessiner la représentation mémoire de l en vous aidant de l’opérateur is pour détecter d’éventuels alias (ex: l[0] is l[1]).
l = [[0] * 4] * 3
  • Effectuer l’affectation ci-dessous, puis afficher l. Représenter le nouvel état de la mémoire et expliquer l’effet de l’affectation.
l[0][0]=1
  • Comment faut-il déclarer l pour que l[0][0]=1 ne modifie que le premier élément de la première sous-liste de l? (en d’autres termes: on veut que chaque entrée de l référence un entier distinct).

Classes

On souhaite définir une classe Rational permettant de représenter des nombres rationnels et d’effectuer des calculs sur ceux-ci.

>>> class Rational:
...    def __init__(self, n=0, d=1):
...        n = n
...        d = d
...
>>> r = Rational()
>>> print(r.n)
Traceback (most recent call last):
  File "<python-input-103>", line 1, in <module>
    print(r.n)
          ^^^
AttributeError: 'Rational' object has no attribute 'n'
  • Expliquer l’erreur ci-dessus. Comment corriger le problème?

Afin de fournir une bonne abstraction via l’encapsulation des données, il est possible d’utiliser les mécanismes suivants:

  • toute variable d’instance débutant par _ ne doit pas être accédée hors de la classe (par convention)
  • toute variable d’instance débutant par __ est obfusquée par l’interpréteur Python afin de la rendre inaccessible (cf. Naming Styles)
  • Ajouter les hooks __str__ et __repr__ permettant d’afficher un objet de type Rational.

  • Programmer la fonction simplify qui met le nombre rationnel sous sa forme réduite.

  • Ajouter les hooks nécessaire à l’utilisation des opérateurs +, -, * et / sur le type Rational.

  • Définir le hook permettant la conversion vers le nombre à virgule flottante représenté par un rationnel.

  • Expliquer l’erreur observée dans le code ci-dessous. Comment modifier le code pour que l’opération l.sort() ci-dessous puisse être effectuée?

>>> l = [Rational(2, 3), Rational(4, 5)]
>>> l.sort()
Traceback (most recent call last):
  File "<python-input-110>", line 1, in <module>
    l.sort()
    ~~~~~~^^
TypeError: '<' not supported between instances of 'Rational' and 'Rational'