Python / Objets et variables
En Python, un objet représente des données avec une valeur et des opérations possibles ; une variable est un nom lié à cet objet. x = 100 lie x à un entier, puis une nouvelle affectation change l’objet désigné. L’affectation ne copie pas automatiquement les objets : plusieurs noms peuvent donc partager la même liste.
Noms, objets et types
Le modèle de données Python attribue aux objets une identité, un type et une valeur. Le type détermine les opérations et propriétés ; l’identité reste stable pendant la vie de l’objet. La possibilité de modifier la valeur dépend du type. Imaginer une variable comme une boîte de type fixe explique mal les nouvelles liaisons et le partage.
Les exemples utilisent Python 3 et la bibliothèque standard. Leurs sorties ont été vérifiées avec Python 3.12.14. Enregistrez chaque code complet en UTF-8 dans objects_demo.py et lancez python objects_demo.py dans un terminal, ou python3 selon l’environnement. Remplacez le contenu pour chaque exemple indépendant.
value = 100
print(value, type(value).__name__)
value = "hello"
print(value, type(value).__name__)
100 int
hello str
value désigne d’abord un int, puis un str. L’entier 100 lui-même n’a pas changé de type. Une affectation évalue l’expression de droite et lie le résultat au nom de gauche. type(value) examine le type de l’objet actuellement désigné.
Partager une liste ou réaffecter un nom
second = first ne crée pas de copie : les deux noms désignent la même liste. Comparez la modification de l’objet partagé et la nouvelle liaison d’un seul nom :
first = [1, 2]
second = first
second.append(3)
print(first)
print(second)
print(first is second)
first = [0]
print(first)
print(second)
print(first is second)
[1, 2, 3]
[1, 2, 3]
True
[0]
[1, 2, 3]
False
append modifie la liste partagée, donc first montre aussi le 3 ajouté. En revanche, first = [0] lie uniquement first à une nouvelle liste. second garde l’ancienne référence. Il faut distinguer la liaison d’un nom du contenu de l’objet désigné.
| Opération | Signification | Effet sur l’autre nom |
|---|---|---|
second = first |
Ajouter un nom pour le même objet | Les deux observent les mutations |
second.append(3) |
Modifier la liste | La lecture de la même liste reflète le changement |
first = [0] |
Lier first à un autre objet | second conserve sa liaison |
Objets immuables et +=
Les entiers, chaînes et tuples sont immuables ; les listes et dictionnaires sont mutables. L’immuabilité concerne l’objet lui-même et n’interdit pas d’affecter une autre valeur à son nom.
first = 10
second = first
first += 1
print(first)
print(second)
11
10
L’entier 10 n’est pas transformé en 11. first est lié au résultat de l’addition, tandis que second désigne toujours 10. Avec une liste, la même syntaxe += peut modifier l’objet existant ; ne généralisez pas son comportement à tous les types. Les références contenues dans un tuple ne peuvent pas être remplacées, mais le contenu d’une liste qu’il contient peut évoluer.
Choisir la profondeur de copie
copy() d’une liste crée une nouvelle liste extérieure : c’est une copie superficielle. Les objets imbriqués restent partagés. Comparez-la à copy.deepcopy() sur les mêmes données initiales :
from copy import deepcopy
original = [[1], [2]]
shallow = original.copy()
deep = deepcopy(original)
shallow[0].append(9)
shallow.append([3])
print(original)
print(shallow)
print(deep)
print(original is shallow)
print(original[0] is shallow[0])
[[1, 9], [2]]
[[1, 9], [2], [3]]
[[1], [2]]
False
True
Ajouter 9 à la liste interne via shallow apparaît aussi dans original. Ajouter [3] à la liste extérieure de shallow n’allonge pas original. deep conserve une copie indépendante des données imbriquées initiales. Déterminez d’abord si le partage est voulu et copiez seulement la portée nécessaire. La copie profonde a un coût et ne duplique pas les fichiers ou sockets comme de simples données.
Égalité et identité : == et is
Pour les listes natives, == compare le contenu et is vérifie qu’il s’agit exactement du même objet. Ces listes ont été créées séparément malgré leur contenu égal :
left = [1, 2]
right = [1, 2]
alias = left
print(left == right)
print(left is right)
print(left is alias)
print(id(left) == id(alias))
missing = None
print(missing is None)
True
False
True
True
True
Employez les opérateurs de comparaison selon leur rôle. id() fournit un entier représentant l’identité ; sa valeur concrète peut changer entre exécutions et n’est pas une adresse mémoire dans toutes les implémentations Python. Ne comparez pas nombres et chaînes avec is en comptant sur la réutilisation d’objets. Utilisez == pour les valeurs et is None pour tester None.
del supprime la liaison d’un nom
del est une instruction, pas une fonction. del first retire la liaison du nom. Un objet reste utilisable par un autre nom qui le désigne encore :
first = [1, 2]
second = first
del first
print(second)
try:
print(first)
except NameError:
print("first: NameError")
try:
del unknown_name
except NameError:
print("unknown_name: NameError")
[1, 2]
first: NameError
unknown_name: NameError
second affiche toujours la liste, mais lire first lève NameError. Supprimer un nom inconnu produit aussi NameError. Selon sa cible, l’instruction del peut supprimer un élément ou un attribut ; elle ne supprime donc pas toujours un nom. Retirer une liaison ne garantit pas une destruction immédiate de l’objet ou la libération de sa mémoire. Fermez les fichiers avec with ou close plutôt qu’en comptant sur del.
Noms valides et lisibles
Avec les caractères latins simples, commencez par une lettre ou un soulignement ; les chiffres sont permis ensuite. Espaces et traits d’union sont interdits, et la casse compte. Python admet également certains caractères Unicode, les noms ne sont donc pas limités aux lettres anglaises.
import keyword
for name in ["user_name", "2name", "class", "first-name", "café", "match"]:
valid = name.isidentifier() and not keyword.iskeyword(name)
print(name, valid)
print("match soft keyword:", keyword.issoftkeyword("match"))
user_name True
2name False
class False
first-name False
café True
match True
match soft keyword: True
isidentifier() accepte la forme de class ; vérifiez donc aussi keyword.iskeyword(). Ici, match est un mot-clé contextuel, pas un mot réservé dans tous les contextes. Consultez la grammaire des identifiants et mots-clés. Les listes peuvent changer selon la version : utilisez le module keyword de votre interpréteur.
Même valides, list ou str peuvent masquer des noms natifs et compliquer leur utilisation. Préférez des noms exprimant le rôle, comme user_name ou item_count. En cas de NameError, vérifiez la casse, l’affectation préalable et la portée où le nom est disponible.




