Comment puis-je exécuter « point » comme une commande à partir de Python?
Question
J'utilise Python sous Mac OS X Leopard.
Je suis en train d'exécuter le 'point' programme (partie de Graphviz) de Python:
# -*- coding: utf-8 -*-
import os
print os.environ['PATH']
print os.system("ls >> a.txt")
print os.system("dot -o9.png -Tpng ./6.dot")
La commande « ls » est là juste pour faire en sorte que python est dans le bon répertoire. Il est. Le résultat que je reçois est:
/ usr / bin: / bin: / usr / sbin: / sbin 0 32512
Ma compréhension est que 32512 erreur signifie que python n'a pas pu trouver le fichier, et depuis le fichier 6.dot est là (Si je lance « point -o9.png -Tpng ./6.dot » du terminal que je reçois aucune erreur et 9.png obtient produit), je suppose que Python ne peut pas trouver le fichier de points.
Je dois probablement ajouter le fichier de point sur le chemin. Mais je ne sais pas où est-il. Si je lance:
whereis dot
Je ne reçois aucune réponse.
Comment puis-je trouver le fichier exécutable dot?
Sinon, je peux exécuter le programme de point comme une commande à l'intérieur Python?
La solution
Vous devez changer la ligne PATH il inclut le répertoire qui contient dot
. Ce répertoire est /usr/local/bin
, sans /dot
.
Autres conseils
whereis
localise les pages de manuel, which
localise les binaires. Donc, essayez which dot
.
Vous devez ajouter le chemin vers l'exécutable « dot » dans l'environnement Python. Vous pouvez le faire en modifiant la variable PATH dans os.environ
Essayez ceci:
# -*- coding: utf-8 -*-
import os
import sys
print os.environ['PATH']
os.environ['PATH'] += ":"+"/usr/local/bin"
print os.environ['PATH']
print os.getcwd()
from subprocess import check_call
print check_call(["dot", "-o9.png", "-Tpng", "./6.dot"])
Tiré de la question pour essayer de maintenir une sorte de bon sens ici.
Conseils de dépannage:
A. ajouter
print os.getcwd()
sur la ligne avant os.system ( "point etc.
Juste pour vous assurer que le répertoire en cours est celui avec le fichier 6.dot
.
B. Assurez-vous que le programme de dot
est dans votre chemin.
which dot
C. Utilisez le chemin complet du programme dot
dans votre commande os.system, voir ce qui se passe alors.
Si vous générez également vos fichiers Dot en Python, pydot fait ce que vous voulez dans d'une manière plus Pythonic:
import pydot
dot = pydot.Dot()
n1, n2 = pydot.Node("a"), pydot.Node("b")
dot.add_node(n1)
dot.add_node(n2)
dot.add_edge(pydot.Edge(n1,n2))
dot.write_png("graph.png", prog='neato')
Souvent, la solution est devant nous,
print os.system("/usr/local/bin/dot -o9.png -Tpng 6.dot")
Vous pouvez également essayer pour tous les points dans un dossier spécifié
import glob
for filedot in glob.glob('*.dot')
print os.system("/usr/local/bin/dot -o9.png -Tpng %(filedot)s"%locals())
#print os.system("/usr/local/bin/dot -o9.png -Tpng %s"%filedot)
Edit:
Je ne me souviens BTW si elle est
/usr/local/bin/dot -o9.png -Tpng fdot.dot
ou
/usr/local/bin/dot -o 9.png -Tpng fdot.dot
Deux suggestions
- Ne pas utiliser PATH, utilisez plutôt « qui » pour trouver juste l'exécutable à la place
- Vous n'utilisez pas « ; » (Point-virgule) pour des chemins séparés, mais ":" (deux points). Une fois que vous changez de cela, il devrait être en mesure de trouver votre programme de points.
Modifier cette
os.environ['PATH'] += ";"+"/usr/local/bin/dot"
à cette
os.environ['PATH'] += ":"+"/usr/local/bin"
Ensuite, votre bien.
EDIT: Notez que j'ai oublié de retirer le / point de la variable PATH moi (oups) - PATH est une liste délimitée par des virgules,
.Au lieu de:
print os.system("dot -o9.png -Tpng ./6.dot")
essayez ceci:
from subprocess import check_call
print check_call("dot -o9.png -Tpng ./6.dot")
Si l'état de sortie du programme de points est 0, l'état est imprimé. Si dot retourne le statut non nul, il soulève CalledProcessError (et spectacles retourne état). Si dot n'existe pas dans le chemin courant, OSError est élevé sous Linux ou sous Windows WindowsErroor (je ne sais pas quelle exception est soulevée sous Mac OS, mais je suppose OSError).
EDIT: Code ci-dessus vous donnera l'indice si vous n'avez pas exécutable point ou d'un fichier 6.dot dans les paramètres de trajet de courant
. check_call
ne pas utiliser la même syntaxe que os.system
, vous devriez donc essayer de changer la ligne correspondante de cette façon:
print check_call(["dot", "-o9.png", "-Tpng", "./6.dot"])
Le nom de l'exécutable est le premier élément du tableau, et chaque paramètre doit être dans un autre élément de la matrice. Sinon, vous toujours obtenez une erreur « Aucun fichier » parce qu'il n'y a pas exécutable nommé « point -o9.png ... » dans votre PATH.
Un problème est dans cette ligne:
os.environ['PATH'] += ":"+"/usr/local/bin/dot"
Vous ne mettez pas le nom de l'exécutable dans le chemin, mais le répertoire contenant l'exécutable. Donc, cela devrait être:
os.environ['PATH'] += ":"+"/usr/local/bin"
Et comme l'a souligné dans un autre commentaire, les arguments check_call
ne sont pas les mêmes que os.system
.
Si vous utilisez une interface graphique telle que Spyder
alors vous pouvez simplement ajouter le chemin bin correct dans le menu des options de PYTHONPATH manager
.
Recherchez l'emplacement du script en faisant cela dans le terminal:
which programname
puis prendre cette position (où il est), soustraire la programname, par exemple:
/home/username/seiscomp3/bin/scart
#this is the section of the path that you use
/home/username/seiscomp3/bin
Ensuite, allez dans le menu des options de PYTHONPATH manager
et ajoutez ce chemin. Ensuite, redémarrez Spyder et que ça va marcher.