Domanda

Sto usando Python su Mac OSX Leopard.

Sto cercando di eseguire il programma 'dot' (parte di Graphviz) da 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")

Il comando "ls" è lì solo per assicurarsi che Python sia nella directory corretta.È.Il risultato che ottengo è:

/usr/bin:/bin:/usr/sbin:/sbin 0 32512

Da quanto ho capito, l'errore 32512 significa che Python non è riuscito a trovare il file e poiché il file 6.dot è presente (se eseguo "dot -o9.png -Tpng ./6.dot" dal terminale non ricevo alcun errore, e 9.png viene prodotto), presumo che Python non riesca a trovare il file punto.

Probabilmente devo aggiungere il file punto al percorso.Ma non so dov'è.Se corro:

whereis dot

Non ricevo risposta.

Come posso trovare l'eseguibile punto?
In alternativa, posso eseguire il programma punto come comando dall'interno di Python?

È stato utile?

Soluzione

Si dovrebbe modificare la riga PATH in modo che includa la directory che contiene dot. Questo elenco è /usr/local/bin senza /dot.

Altri suggerimenti

whereis individua le pagine man, which individua i binari. Quindi provare which dot.

È necessario aggiungere il percorso del file eseguibile 'dot' in un ambiente Python. È possibile farlo modificando la variabile PATH in os.environ

Prova questo:

# -*- 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"])

Preso dalla questione per cercare di mantenere una sorta di sanità mentale qui.

Risoluzione dei problemi:

A. aggiungi

print os.getcwd()

sulla linea prima os.system ( "Dot ecc.

Solo per fare in modo che la directory corrente è quella con il file 6.dot.

B. Assicurarsi che il programma dot è nel tuo percorso.

which dot

C. Utilizzare il percorso completo del programma dot nel comando os.system, vedere cosa succede poi.

Se anche si generano i file Dot in Python, pydot fa ciò che vuoi in un modo più 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')

Spesso la soluzione è davanti a noi,

print os.system("/usr/local/bin/dot -o9.png -Tpng 6.dot")

Inoltre puoi provare tutti i punti in una cartella specificata

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)

Modificare:

Comunque non riesco a ricordare se lo è

/usr/local/bin/dot -o9.png -Tpng fdot.dot

O

/usr/local/bin/dot -o 9.png -Tpng fdot.dot

Due suggerimenti

  1. Non utilizzare PATH, invece usare "che" per trovare solo l'eseguibile invece
  2. Non si utilizza ";" (Punto e virgola) per percorsi separati, ma ":" (due punti). Una volta che si cambia questa dovrebbe essere in grado di trovare il vostro programma di punti.

Modificare questo

os.environ['PATH'] += ";"+"/usr/local/bin/dot"

a questo

os.environ['PATH'] += ":"+"/usr/local/bin"

Quindi il vostro bene.

EDIT: Si noti che ho dimenticato di rimuovere il / punti dalla variabile PATH me (oops) - PATH è un elenco delimitato da due punti di directory

.

Al posto di:

print os.system("dot -o9.png -Tpng ./6.dot")

provare questo:

from subprocess import check_call
print check_call("dot -o9.png -Tpng ./6.dot")

Se lo stato di uscita del programma di punto è 0, lo stato viene stampato. Se dot ritorna stato diverso da zero, solleva CalledProcessError (e spettacoli restituito di stato). Se dot non esiste nel percorso corrente, OSError è sollevata su Linux o su Windows WindowsErroor (non so quale viene sollevata un'eccezione in Mac OS, ma suppongo OSError).

EDIT: Codice sopra vi darà il suggerimento se non avete eseguibile o un file dot 6.dot in impostazioni del percorso attuale

.

check_call non usa la stessa sintassi os.system, così si dovrebbe provare a cambiare la riga corrispondente in questo modo:

print check_call(["dot", "-o9.png", "-Tpng", "./6.dot"])

Il nome eseguibile è il primo elemento dell'array, e ogni parametro deve essere in un altro elemento della matrice. Altrimenti si sempre ottiene un "No such file" errore perché non c'è eseguibile chiamato "dot -o9.png ..." nel PATH.

Un problema è in questa linea:

os.environ['PATH'] += ":"+"/usr/local/bin/dot"

non mettere il nome del file eseguibile nel percorso, ma la directory contenente il file eseguibile. In modo che dovrebbe essere:

os.environ['PATH'] += ":"+"/usr/local/bin"

E come sottolineato in un altro commento, gli argomenti a check_call non sono le stesse di os.system.

Se si utilizza una GUI, come Spyder allora si può semplicemente aggiungere il percorso bin corretto nel menu delle opzioni PYTHONPATH manager.

Cerca l'ubicazione dello script facendo questo nel terminale:

which programname

poi prendere quella posizione (ovunque essa sia), sottrarre il ProgramName, ad esempio:

/home/username/seiscomp3/bin/scart
#this is the section of the path that you use
/home/username/seiscomp3/bin

Poi vai nel menu delle opzioni PYTHONPATH manager e aggiungere questo percorso. Quindi riavviare Spyder e funzionerà.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top