web-dev-qa-db-fra.com

Comment éviter les fichiers .pyc?

Puis-je exécuter l'interpréteur python sans générer les fichiers .pyc compilés?

252
Avner

De "Nouveautés de Python 2.6 - Modifications d’interpréteur" :

Python peut maintenant être empêché de écrire des fichiers .pyc ou .pyo par fournir le commutateur -B au Python interprète, ou en réglant le paramètre PYTHONDONTWRITEBYTECODE environment variable avant d'exécuter le interprète. Ce paramètre est disponible aux programmes Python en tant que sys.dont_write_bytecode variable, et Le code Python peut changer la valeur en modifier le comportement de l'interprète.

Mise à jour 2010-11-27: Python 3.2 résout le problème de l'encombrement des dossiers source avec les fichiers .pyc en introduisant un sous-dossier __pycache__ spécial, voir Nouveautés de Python 3.2 - Répertoires de référentiel PYC .

280
Constantin
import sys

sys.dont_write_bytecode = True
100
te wilson

Il existe en fait IS un moyen de le faire dans Python 2.3+, mais c'est un peu ésotérique. Je ne sais pas si vous vous en rendez compte, mais vous pouvez faire ce qui suit:

$ unzip -l /tmp/example.Zip
 Archive:  /tmp/example.Zip
   Length     Date   Time    Name
 --------    ----   ----    ----
     8467  11-26-02 22:30   jwzthreading.py
 --------                   -------
     8467                   1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32) 
>>> import sys
>>> sys.path.insert(0, '/tmp/example.Zip')  # Add .Zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.Zip/jwzthreading.py'

Selon la bibliothèque zipimport :

Tous les fichiers peuvent être présents dans l’archive Zip, mais seuls les fichiers .py et .py [co] sont disponibles à l’importation. L'importation zip de modules dynamiques (.pyd, .so) n'est pas autorisée. Notez que si une archive ne contient que des fichiers .py, Python n'essaiera pas de la modifier en ajoutant le fichier .pyc ou .pyo correspondant, ce qui signifie que si une archive Zip ne contient pas de fichiers .pyc, l'importation risque d'être assez lente.

Ainsi, tout ce que vous avez à faire est de compresser les fichiers, ajoutez le fichier zip à votre sys.path, puis importez-les.

Si vous construisez cela pour UNIX, vous pouvez également envisager de conditionner votre script à l'aide de la recette suivante: exécutable unix Zip , mais notez qu'il peut être nécessaire d'ajuster ceci si vous envisagez d'utiliser stdin ou de lire quoi que ce soit à partir de sys.args (cela peut être fait sans trop de problèmes).

D'après mon expérience, les performances n'en pâtissent pas trop, mais vous devez réfléchir à deux fois avant d'importer de très gros modules de cette façon.

22
Jason Baker

En 2.5, il n'y a aucun moyen de le supprimer, hormis des mesures telles que le fait de ne pas donner aux utilisateurs un accès en écriture au répertoire.

Cependant, en python 2.6 et 3.0, il peut exister un paramètre dans le module sys appelé "dont_write_bytecode" pouvant être défini pour le supprimer. Cela peut également être défini en passant l'option "-B" ou en définissant la variable d'environnement "PYTHONDONTWRITEBYTECODE".

11
Brian

Vous pouvez définir sys.dont_write_bytecode = True dans votre source, mais cela devrait être dans le premier fichier python chargé. Si vous exécutez python somefile.py, vous n'obtiendrez pas somefile.pyc.

Lorsque vous installez un utilitaire à l'aide de setup.py et entry_points=, vous aurez défini sys.dont_write_bytecode dans le script de démarrage. Vous ne pouvez donc pas vous fier au script de démarrage "par défaut" généré par setuptools.

Si vous démarrez Python avec un fichier python en tant qu'argument, vous pouvez spécifier -B:

python -B somefile.py

De toute façon, somefile.pyc ne serait pas généré, mais aucun fichier .pyc pour les autres fichiers importés également.

Si vous avez un utilitaire myutil et que vous ne pouvez pas le modifier, il ne passera pas -B à l'interpréteur python. Commencez simplement par définir la variable d'environnement PYTHONDONTWRITEBYTECODE:

PYTHONDONTWRITEBYTECODE=x myutil
6
Elwyne

J'ai plusieurs cas de test dans une suite de tests et avant d'exécuter la suite de tests dans le terminal Mac, comme ceci: 

python LoginSuite.py

En exécutant la commande de cette manière, mon répertoire était rempli de fichiers .pyc. J'ai essayé la méthode indiquée ci-dessous et cela a résolu le problème:

python -B LoginSuite.py

Cette méthode fonctionne si vous importez des scénarios de test dans la suite de tests et exécutez la suite sur la ligne de commande. 

3
Ravil Asadov

Vous pouvez créer les répertoires contenant vos modules en lecture seule pour l'utilisateur exécutant l'interpréteur Python.

Je ne pense pas qu'il existe une option plus élégante. PEP 304 semble avoir été une tentative d'introduire une option simple pour cela, mais cela semble avoir été abandonné.

J'imagine qu'il y a probablement un autre problème que vous essayez de résoudre, pour lequel désactiver .py [co] semblerait être une solution de contournement, mais il vaudra probablement mieux s'attaquer à ce problème original.

1
Logan

Solution pour ipython 6.2.1 using python 3.5.2 (testé sous Ubuntu 16.04 et Windows 10):

Ipython ne respecte pas %env PYTHONDONTWRITEBYTECODE =1 s'il est défini dans l’interprète ipython ou lors du démarrage dans ~/.ipython/profile-default/startup/00-startup.ipy..__ Au lieu d’utiliser le code suivant dans votre ~.ipython/profile-default/startup/00-startup.py

import sys
Sys.dont_write_bytecode=True
0
alpha_989

Autant que je sache, python compilera tous les modules que vous "importez". Cependant, python NE compilera PAS un script python exécuté avec: "python script.py" (il compilera toutefois tous les modules importés par le script).

La vraie question est pourquoi vous ne voulez pas que python compile les modules? Vous pourriez probablement automatiser un moyen de les nettoyer s'ils gênent.

0
Alex

À partir de Python 3.8, vous pouvez utiliser la variable d'environnement PYTHONPYCACHEPREFIX pour définir un répertoire de cache pour Python.

À partir de la docs Python:

Si cette option est définie, Python écrira les fichiers .pyc dans une arborescence de répertoires miroir sur ce chemin, au lieu de dans les répertoires pycache de l'arborescence source. Cela équivaut à spécifier l'option -X pycache_prefix = PATH.

Exemple

Si vous ajoutez la ligne suivante à votre ./profile sous Linux:

export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"

Python ne créera pas les répertoires gênants __pycache__ dans votre répertoire de projet, mais les mettra tous sous ~/.cache/cpython/

0
Rotareti