-1
votes

Quand exécuter des commandes externes à Python

en Python, il est possible d'exécuter une commande bash pour atteindre quelque chose qui peut être atteint en fonction du code Python équivalent. Comme exemple simple, sur CD code> dans un répertoire et faire des trucs, vous pouvez faire soit:

import os
os.chdir(path) # path is the path to the directory
#do other stuff


0 commentaires

3 Réponses :


1
votes

La première version change simplement le répertoire de la sous-processus. Il n'a aucun effet sur le processus d'origine Python, il est donc pratiquement inutile. Cela ne serait utile que s'il faisait partie de plusieurs commandes: xxx

La deuxième version modifie le répertoire du processus Python lui-même.

plus généralement, s'il y a Fonction Python qui fait la même chose qu'une commande externe, vous devez préférer la fonction. Il est plus efficace car il n'a pas besoin de démarrer un nouveau processus, il n'est pas nécessaire d'analyser la commande si vous utilisez shell = true et que vous obtenez une manipulation plus flexible d'erreur.


3 commentaires

J'ajouterais que vous devriez souvent essayer d'utiliser des fonctions de la bibliothèque standard. Ils sont garantis pour être une plate-forme croisée, sont plus claires à lire, sont plus efficaces et comme indiqué ici sont plus simples à comprendre


Oui, je viens de choisir un exemple simple, mais quelle serait la différence en général dans le fonctionnement des commandes de Python Code vs Bash pour atteindre une tâche donnée (je mettrai à jour ma question)


En général, s'il y a une fonction pour faire quelque chose, il n'y a aucune raison d'utiliser une commande externe pour cela.



1
votes

Je ne choisirais pas le premier. Il crée un sous-processus et des modifications apportées au répertoire à l'intérieur de cette sous-processus, qui met ensuite fin à la sortie du répertoire actuel du processus Python, comme avant la sous-processus.run appel.

os.chdir modifie réellement le répertoire de travail du processus en cours. Ce qui semble bien jusqu'à ce que vous commenciez à utiliser des threads et réalisez que le répertoire actuel d'un thread peut être affecté par un appel os.chdir d'un autre fil.

Pour les processus à une seule-filetage (le type d'ingorant erré pourrait généralement écrire initialement) cela ne présente aucun problème.

Plus largement, attendez-vous à utiliser le module de sous-processus Si vous avez besoin de plus de parallélisme que Python peut fournir seul (recherche "Python Gil" pour savoir pourquoi les processus Python naïf ne peuvent utiliser qu'un noyau d'un multicœur ordinateur).


1 commentaires

Intéressant. Je travaille en fait sur un exemple de code multithreading! Merci d'avoir souligné que cela aide



1
votes

niher. SUBPROCESS.RUN ('"DISTRIBUTION DE CD") Il suffit de modifier le répertoire du sous-processus qui est alors sorti, supprimant ce contexte-répertoire modifié. OS.CHDIR (Chemin) n'est pas toujours fou, seulement 99% d'insensé. Vous ferez mieux d'utiliser OS.Path ou pathlib pour suivre les répertoires et ne pas changer ce que "actuel" signifie tout au long du programme.

Il existe un avantage pour exécuter des commandes externes, surtout si elles implémentent des fonctionnalités que vous n'avez pas pour le moment. Ils peuvent également aider à paralleraliser votre code, tel que fonctionnant un Grep External et en utilisant ses résultats. Qui présente l'inconvénient d'ajouter des dépendances de la plate-forme externes.

fréquemment, c'est seulement parce que le programmeur comprend mieux la coquille que Python. Ou trouvé un exemple de coque sur le net. C'est bien pour un amateur non pas une base de code professionnelle.

Disclaimer: IMHO


6 commentaires

Appeler l'utilisation de Os.chdir "99% fou" est franchement ridicule.


@cheppner - D'accord, 98%. C'est deux fois plus bon! Du point de vue de l'utilisateur "Répertoire actuel" est le répertoire que l'utilisateur se trouvait lorsque la commande a été lancée. L'utilisateur peut raisonnablement s'attendre à ce qu'un chemin relatif soit relatif à sa CWD. Mais pour Guis et tout ce qui peut obtenir des chemins de fichiers de configuration ou des variables d'environnement, ou même une boîte de dialogue d'interface graphique, à l'aide de OS.Path ou pathlib par rapport à ces variables est le chemin supérieur . J'ai du mal à penser à un cas que j'ai rencontré où os.chdir était une bonne idée.


J'ai du mal à penser à une bonne raison d'assumer que le répertoire de base de l'utilisateur sera le répertoire de travail actuel du programme. Si vous souhaitez faire cette hypothèse, démarrez votre programme avec os.chdir (os.environ ["home"]) serait un moyen de s'assurer que.


@cheppner - et inversement, os.chdir éparpillé autour de votre code est presque garanti d'être un cauchemar de débogage. "foo / bar / baz.txt" a fonctionné plus tôt, pourquoi pas maintenant?


@cheppnet - Je vais faire des bagages à penser à une raison de supposer que le répertoire de base de l'utilisateur est un bon candidat à la CWD forcée, quel que soit le point initial où le programme a été lancé. Comme vous le dites, "home" est juste là pour tout ce que vos besoins de code soient basés sur votre code. Pas besoin de CHDIR .


Traiter os.chdir comme une déclaration d'affectation. Les variables mondiales mutables sont une mauvaise idée; Global Constantes va bien. Utilisez os.chdir pour définir le répertoire de travail sur un état de connaître une fois , vous pouvez utiliser des chemins relatifs en toute sécurité dans votre code sans utiliser os.path.join < / code> à plusieurs reprises. (Ou utilisez os.path.join comme vous l'avez mentionné, mais à nouveau une fois pour définir une constante globale.)