web-dev-qa-db-fra.com

Les objets datetime doivent-ils être copiés en profondeur?

J'ai donc remarqué l'autre semaine en exécutant une expérience, que, bien qu'il s'agisse d'un langage de haut niveau, vous pouvez faire des copies de variables en les affectant simplement comme ceci:

a = 5    
b = a
print(b) # 5
b = 3
print(b) # 3
print(a) # 5

... si vous traitez les dictionnaires ou éventuellement les listes de la même manière, cela se décolle! J'ai créé un bogue dans mon code l'autre semaine en pensant que les dictionnaires fonctionnaient de la même manière. J'ai découvert que pour faire une copie correcte et complète, vous devez aller:

b = dict(a)

Quoi qu'il en soit, je suis occupé avec des objets datetime et je les manipule comme s'ils étaient des entiers, commençant maintenant à devenir un peu nerveux quant à savoir si cela va bien. Tout cela semble un peu arbitraire là où cela fonctionne et là où il ne fonctionne pas, dois-je exécuter une expérience à chaque fois juste pour vérifier son comportement? Peut deviner que les chaînes fonctionnent probablement comme des entiers mais ne savent pas où le comportement change.

Peut voir quelqu'un a demandé ceci pour PHP mais pour Python je suis enclin à penser que toute affectation d'un objet datetime serait une copie correcte et complète et ne gâcherait jamais accidentellement avec la variable d'origine. Quelqu'un est-il sûr?

14
cardamom

Puisque tous les types disponibles dans le module datetime sont documentés comme étant immuables (juste après la documentation des classes, il est indiqué):

Les objets de ces types sont immuables.

vous ne devriez pas vous en soucier.

Les opérations sur une instance datetime renverront une nouvelle instance, n'affectant ainsi aucun autre nom faisant référence au précédent.

Vous voudrez peut-être jeter un œil au lien fourni par PM 2Ring qui explique faits et mythes sur le fonctionnement des noms et des valeurs . Cela devrait éclairer toute confusion vous avez des noms.

20

Il n'y a rien d'arbitraire à cela.

Toutes les affectations dans Python sont des références. Aucune copie n'est jamais effectuée sur l'affectation.

Si vous avez la possibilité de muter l'objet, toute mutation affectera naturellement toutes les références à cet objet.

La seule raison pour laquelle vous ne voyez pas cela avec des entiers ou des chaînes dans votre code d'origine est que vous ne modifiez pas les objets, vous êtes simplement en train de réaffecter. Les entiers et les chaînes, ainsi que les horaires, n'ont aucun moyen d'être mutés, donc la seule chose que vous pouvez faire est de les réaffecter. Si vous réaffectez une liste, un dict ou une datetime, vous ne verrez pas non plus la modification propagée à d'autres références.

8
Daniel Roseman