Как запустить «точку» как команду Python?
Вопрос
Я использую Python на Mac OSX Leopard.
Я пытаюсь запустить программу «точка» (часть Graphviz) из 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")
Команда «ls» нужна только для того, чтобы убедиться, что Python находится в правильном каталоге.Это.Результат, который я получаю:
/usr/bin:/bin:/usr/sbin:/sbin 0 32512
Насколько я понимаю, ошибка 32512 означает, что Python не смог найти файл, и поскольку файл 6.dot существует (если я запускаю «dot -o9.png -Tpng ./6.dot» с терминала, я не получаю никакой ошибки, и создается 9.png), я предполагаю, что Python не может найти точечный файл.
Вероятно, мне нужно добавить точечный файл в путь.Но я не знаю, где это.Если я бегу:
whereis dot
Я не получаю ответа.
Как я могу найти исполняемый файл точки?
Альтернативно, могу ли я запустить точечную программу как команду изнутри Python?
Решение
Вам следует изменить строку PATH, чтобы она включала каталог, содержащий dot
.Этот каталог /usr/local/bin
, без /dot
.
Другие советы
whereis
находит справочные страницы, which
находит двоичные файлы.Поэтому постарайтесь which dot
.
Вам нужно добавить путь к исполняемому файлу «точка» в среде Python.Вы можете сделать это, изменив переменную PATH в os.environ.
Попробуй это:
# -*- 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"])
Взято из вопроса, чтобы попытаться сохранить здесь какое-то здравомыслие.
Советы по устранению неполадок:
А.добавлять
print os.getcwd()
в строке перед os.system("точка и т.д.
Просто чтобы убедиться, что текущий каталог — это тот, в котором находится 6.dot
файл.
Б.Убедитесь, что dot
программа находится на вашем пути.
which dot
С.Используйте полный путь к dot
в вашей команде os.system, посмотрите, что произойдет потом.
Если вы также создаете файлы Dot на Python, пидот делает то, что вы хотите, более 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')
Часто решение находится перед нами,
print os.system("/usr/local/bin/dot -o9.png -Tpng 6.dot")
Также вы можете попробовать все точки в указанной папке.
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)
Редактировать:
Я не могу вспомнить, кстати, если это так
/usr/local/bin/dot -o9.png -Tpng fdot.dot
или
/usr/local/bin/dot -o 9.png -Tpng fdot.dot
Два предложения
- Не используйте PATH, вместо этого используйте «который», чтобы просто найти исполняемый файл.
- Вы не используете ";" (полуколон) для разделения путей, но ":" (толстой кишки).Как только вы измените это, он сможет найти вашу точечную программу.
Изменить это
os.environ['PATH'] += ";"+"/usr/local/bin/dot"
к этому
os.environ['PATH'] += ":"+"/usr/local/bin"
Тогда все в порядке.
РЕДАКТИРОВАТЬ:Обратите внимание, что я сам забыл удалить /точку из переменной PATH (упс) — PATH — это список каталогов, разделенный двоеточиями.
Вместо:
print os.system("dot -o9.png -Tpng ./6.dot")
попробуй это:
from subprocess import check_call
print check_call("dot -o9.png -Tpng ./6.dot")
Если статус выхода точечной программы равен 0, статус выводится на печать.Если точка возвращает ненулевой статус, она вызывает CalledProcessError (и показывает возвращенный статус).Если точка не существует в текущем пути, возникает OSError в Linux или WindowsErroor в Windows (я не знаю, какое исключение возникает в Mac OS, но я предполагаю, что OSError).
РЕДАКТИРОВАТЬ:Код выше даст вам подсказку, если у вас нет исполняемого файла с точкой или файла 6.dot в текущих настройках пути.
check_call
не использует тот же синтаксис, что и os.system
, поэтому попробуйте изменить соответствующую строку следующим образом:
print check_call(["dot", "-o9.png", "-Tpng", "./6.dot"])
Имя исполняемого файла — это первый элемент массива, и каждый параметр должен находиться в другом элементе массива.В противном случае вы будете всегда получите ошибку «Нет такого файла», поскольку в вашем PATH нет исполняемого файла с именем «dot -o9.png ...».
Одна проблема в этой строке:
os.environ['PATH'] += ":"+"/usr/local/bin/dot"
В пути вы указываете не имя исполняемого файла, а каталог, содержащий исполняемый файл.Итак, это должно быть:
os.environ['PATH'] += ":"+"/usr/local/bin"
И, как указано в другом комментарии, аргументы в пользу check_call
не то же самое, что os.system
.
Если вы используете графический интерфейс, например Spyder
то вы можете просто добавить правильный путь к контейнеру в PYTHONPATH manager
меню опций.
Найдите местоположение скрипта, выполнив это в терминале:
which programname
затем возьмите это место (где бы оно ни было), вычтите имя программы, например:
/home/username/seiscomp3/bin/scart
#this is the section of the path that you use
/home/username/seiscomp3/bin
Затем зайдите в PYTHONPATH manager
меню параметров и добавьте этот путь.Затем перезапустите Spyder, и все заработает.