Exécution de code Python avec l'option -m ou non
Utilisez le -m
drapeau.
Les résultats sont à peu près les mêmes lorsque vous avez un script, mais lorsque vous développez un package, sans l' -m
indicateur, il n'y a aucun moyen de faire fonctionner correctement les importations si vous souhaitez exécuter un sous-package ou un module dans le package en tant qu'entrée principale montrez votre programme (et croyez-moi, j'ai essayé.)
Les docs
Comme les documents sur l'indicateur -m disent:
Recherchez dans sys.path le module nommé et exécutez son contenu en tant que __main__
module.
et
Comme avec l'option -c, le répertoire courant sera ajouté au début de sys.path.
alors
python -m pdb
équivaut à peu près à
python /usr/lib/python3.5/pdb.py
(en supposant que vous n'avez pas de package ou de script dans votre répertoire actuel appelé pdb.py)
Explication:
Le comportement est rendu «délibérément similaire aux» scripts.
De nombreux modules de bibliothèque standard contiennent du code qui est appelé lors de leur exécution en tant que script. Un exemple est le module timeit:
Un certain code python est destiné à être exécuté en tant que module: (Je pense que cet exemple est meilleur que l'exemple de doc d'option de ligne de commande)
$ python -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 40.3 usec per loop
$ python -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 3: 33.4 usec per loop
$ python -m timeit '"-".join(map(str, range(100)))'
10000 loops, best of 3: 25.2 usec per loop
Et d'après les faits saillants de la note de publication pour Python 2.4 :
L'option de ligne de commande -m - python -m nom_module trouvera un module dans la bibliothèque standard et l'invoquera. Par exemple, python -m pdb
équivaut àpython /usr/lib/python2.4/pdb.py
Question de suivi
De plus, le Python Essential Reference de David Beazley l'explique comme suit: «L'option -m exécute un module de bibliothèque comme un script qui s'exécute à l'intérieur du __main__
module avant l'exécution du script principal».
Cela signifie que tout module que vous pouvez rechercher avec une instruction d'importation peut être exécuté comme point d'entrée du programme - s'il a un bloc de code, généralement vers la fin, avec if __name__ == '__main__':
.
-m
sans ajouter le répertoire courant au chemin:
Un commentaire ici ailleurs dit:
Que l'option -m ajoute également le répertoire courant à sys.path, est évidemment un problème de sécurité (voir: attaque de préchargement). Ce comportement est similaire à l'ordre de recherche des bibliothèques dans Windows (avant qu'il ne soit durci récemment). C'est dommage que Python ne suive pas la tendance et n'offre pas un moyen simple de désactiver l'ajout. vers sys.path
Eh bien, cela démontre le problème possible - (dans Windows, supprimez les guillemets):
echo "import sys; print(sys.version)" > pdb.py
python -m pdb
3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
Utilisez l' -I
indicateur pour verrouiller cela pour les environnements de production (nouveau dans la version 3.4):
python -Im pdb
usage: pdb.py [-c command] ... pyfile [arg] ...
etc...
à partir de la documentation :
-I
Exécutez Python en mode isolé. Cela implique également -E et -s. En mode isolé, sys.path ne contient ni le répertoire du script ni le répertoire site-packages de l'utilisateur. Toutes les variables d'environnement PYTHON * sont également ignorées. D'autres restrictions peuvent être imposées pour empêcher l'utilisateur d'injecter du code malveillant.
Que fait __package__
-on?
Cela permet des importations relatives explicites, pas particulièrement pertinentes pour cette question, cependant - voir cette réponse ici: Quel est le but de l'attribut «__package__» en Python?
PYTHONPATH=test python -m foo.bar
signifie réellement la commande ? Pourriez-vous l'expliquer en détail, s'il vous plaît?