Ответ 1
Используйте подпроцесс. Вместо этого.
http://docs.python.org/library/subprocess.html#subprocess-replacements
http://docs.python.org/library/subprocess.html#subprocess.Popen
В документе os.popen есть заметка об этом.
Я пытаюсь реализовать нечто похожее на git log
, которое будет выводить только страницу вывода, если журнал имеет определенную длину. Если вы не знакомы с git, я по существу пытаюсь это сделать:
python some_script.py | less
С некоторой помощью реализации пейджинга в python2.6/pydoc.py я смог придумать следующее:
import os
text = '...some text...'
pipe = os.popen('less', 'w')
pipe.write(text)
pipe.close()
который отлично работает, но os.popen() устарел. Я рассмотрел запись в временном файле и меньше ссылаюсь на его путь, но это не кажется идеальным. Возможно ли это с подпроцессом? Любые другие идеи?
EDIT:
Итак, я получил подпроцесс. Мне удалось передать текстовую переменную с помощью Popen.communicate(text)
, но поскольку я действительно хочу перенаправить инструкции печати, я решил:
import os, sys, subprocess, tempfile
page = True
if page:
path = tempfile.mkstemp()[1]
tmp_file = open(path, 'a')
sys.stdout = tmp_file
print '...some text...'
if page:
tmp_file.flush()
tmp_file.close()
p = subprocess.Popen(['less', path], stdin=subprocess.PIPE)
p.communicate()
sys.stdout = sys.__stdout__
Конечно, я бы включил его в функции. Кто-нибудь видит проблему с этим?
Используйте подпроцесс. Вместо этого.
http://docs.python.org/library/subprocess.html#subprocess-replacements
http://docs.python.org/library/subprocess.html#subprocess.Popen
В документе os.popen есть заметка об этом.
Как насчет этого:
import pydoc
text = '... some text ... '
pydoc.pager(text)
Это (в моем окне openuse linux) отправляет текст на пейджер ( "меньше" в моем случае) и работает так же, как вызов "help (... python command...)" в интерпретаторе Python.
Это хорошая идея быть явным в вашем коде, так что она показывает, что вы используете специальную функцию печати printc()
вместо стандартной. Использование subprocess.call()
также является достаточным (вам не нужно оборудование для труб). Кроме того, вы можете сохранить переменную, не сохраняя имя временного файла:
from __future__ import print_function
import subprocess, tempfile
page = True # For tests
# Definition of a printc() function that prints to the correct output
if page:
tmp_file = open(tempfile.mkstemp()[1], 'w') # No need to store the name in a specific variable
def printc(*largs, **kwargs):
if 'file' not in kwargs: # The code can still use the usual file argument of print()
kwargs['file'] = tmp_file # Forces the output to go to the temp file
print(*largs, **kwargs)
else:
printc = print # Regular print
# Main program:
printc('...some text...', 'some more text', sep='/') # Python3 syntax
# Paging of the current contents of the temp file:
if page:
tmp_file.flush() # No need to close the file: you can keep printing to it
subprocess.call(['less', tmp_file.name]) # Simpler than a full Popen()
Таким образом, вы получаете гибкость функции Python 3 print
, с кодом, который явно показывает, что вы делаете какие-то причудливые печатные материалы. Это масштабируется лучше с большими программами, чем изменение "глобальной" переменной sys.stdout
в некоторых местах вашего кода.
Мне не нравилось выполнять внешние команды, поэтому я написал pager в чистом Python. У него все еще есть проблема - вход в канал работает только для Windows.