web-dev-qa-db-fra.com

Quand les fichiers .pyc sont-ils actualisés?

Je comprends que les fichiers ".pyc" sont des versions compilées des fichiers ".py" en clair, créés au moment de l’exécution pour rendre les programmes plus rapides. Cependant, j'ai observé quelques choses:

  1. Lors de la modification des fichiers "py", le comportement du programme change. Cela indique que les fichiers "py" sont compilés ou du moins passent par une sorte de processus de hachage ou comparent des horodatages afin de dire s'ils doivent ou non être recompilés.
  2. Lors de la suppression de tous les fichiers ".pyc" (rm *.pyc) parfois le comportement du programme change. Ce qui indiquerait qu'ils ne sont pas compilés lors de la mise à jour de ".py" s.

Des questions:

  • Comment décident-ils quand être compilé?
  • Y a-t-il un moyen de s'assurer que leurs contrôles sont plus stricts pendant le développement?
83
Aaron Schif

Les fichiers .pyc sont créés (et éventuellement remplacés) uniquement lorsque ce fichier python est importé par un autre script. Si l'importation est appelée, Python vérifie si l'horodatage interne du fichier .pyc n'est pas plus ancien que le fichier .py correspondant. Si c'est le cas, il charge le .pyc; si ce n'est pas le cas ou si le .pyc n'existe pas encore, Python compile le fichier .py en un .pyc et le charge.

Qu'entendez-vous par "vérification plus stricte"?

70
DaveTheScientist

Les fichiers .pyc sont générés à chaque fois que les éléments de code correspondants sont importés et mis à jour si les fichiers de code correspondants ont été mis à jour. Si les fichiers .pyc sont supprimés, ils seront automatiquement régénérés. Cependant, ils ne sont pas non automatiquement supprimés lorsque les fichiers de code correspondants sont supprimés.

Cela peut causer des bugs très amusants lors des refactors au niveau des fichiers.

Tout d'abord, vous pouvez vous retrouver à pousser du code qui ne fonctionne que sur votre machine et sur personne d'autre. Si vous avez des références en suspens aux fichiers que vous avez supprimés, ceux-ci continueront de fonctionner localement si vous ne supprimez pas manuellement les fichiers .pyc appropriés, car les fichiers .pyc peuvent être utilisés dans les importations. Cela est aggravé par le fait qu'un système de contrôle de version correctement configuré ne transmettra que les fichiers .py au référentiel central, et non les fichiers .pyc, ce qui signifie que votre code peut passer le "test d'importation" (l'importation est-elle correcte) sans problème travailler sur l'ordinateur de quelqu'un d'autre.

Deuxièmement, vous pouvez avoir des bugs assez terribles si vous transformez des paquets en modules. Lorsque vous convertissez un package (un dossier avec un fichier __init__.py) En un module (un fichier .py), les fichiers .pyc qui représentaient ce package sont conservés. En particulier, le __init__.pyc Reste. Donc, si vous avez le paquet foo avec du code qui n’a pas d’importance, supprimez-le plus tard et créez un fichier foo.py avec une fonction def bar(): pass et exécutez:

from foo import bar

vous recevez:

ImportError: cannot import name bar

parce que python utilise encore les anciens fichiers .pyc du paquet foo, aucun d’entre eux ne définissant barre. Cela peut être particulièrement problématique sur un serveur Web, où un code totalement fonctionnel peut se briser à cause de .pyc des dossiers.

En raison de ces deux raisons (et éventuellement d'autres), votre code de déploiement et votre code de test doivent supprimer les fichiers .pyc, comme avec la ligne suivante de bash:

find . -name '*.pyc' -delete

De plus, à compter de python 2.6, vous pouvez exécuter python avec l'indicateur -B Pour ne pas utiliser les fichiers .pyc. Voir Comment éviter les fichiers .pyc? pour plus de détails.

Voir aussi: Comment puis-je supprimer tous les fichiers .pyc d'un projet?

29
Zags