Python CGI: перевод из stdout в html (например, заменить \ n на <BR>) - PullRequest
1 голос
/ 03 июля 2011

У меня есть отличная программа командной строки, которая печатает на стандартный вывод. Я хочу позволить людям управлять этим через CGI. В версии CGI я хочу иметь тот же вывод (с "<BR>" вместо "\n").

Мой cgi_main работает по телефону my real_main; Есть много вариантов для обработки, и это было плохим дизайном, чтобы сделать это несколько раз. Но поскольку real_main звонит print, я не знаю, как изменить "\n" на "<BR>" post hoc.

Я мог бы легко изменить все экземпляры print, чтобы перейти к tempfile, а затем сбросить его в конце, но, кажется, нелегко изменить существующую версию командной строки.

Один из вариантов - real_main вызывать другую функцию (передавая argv); эта новая функция возвращает значения. Затем real_main печатает эти значения. cgi_main будет вызывать ту же функцию, но печатать значения по-разному.

Другой вариант - использовать член класса / статическую функцию везде, где я сейчас использую print. Этот класс может быть сказано, переформатировать или нет. Тогда переключение между командной строкой и выводом CGI просто потребует изменения аргумента reform.

Вот пример того, как я думал, что этот класс и функция могут работать: Класс cgi_tools: def init (self, реформ = False): self.reform = реформа def myprint (self, * args): если не self.reform: печать (арг) для i, x в перечислении (args): if type (x) == str: self.myprint (x.replace ('\ n', '
')), Тип elif (x) в атомах: # проверьте, является ли x атомом (то есть int, float и т. д.): печать х, еще: self.myprint (х), если i! = len (args) -1: Распечатать ' ', print ''

С этим я столкнулся с проблемой, пытаясь придумать все атомы (т.е. неприводимые объекты) в Python. Мне не удалось найти встроенную функцию для этого теста, и я подумал, что написать ее самому себе - хрупкая идея.

Я пытался использовать insepct для печати исходного кода print, но я не смог этого сделать! print sys.out.print:

import inspect
print inspect.getsource(print) # this does not work!

Все это похоже на классический вопрос Python CGI, но я не смог найти отличного решения. Я знаю, как неуклюже соединять вещи и получать то, что я хочу, но мне бы очень хотелось, чтобы вы посоветовали, как быть элегантным. Я хочу развиваться и больше не хочу программировать небрежно.

Большое спасибо за ваши мысли и советы.
-Oliver

1 Ответ

2 голосов
/ 03 июля 2011

В начале вашего CGI-скрипта поставьте print "Content-type: text/plain\r\n\r\n". Результат будет отображаться на веб-странице так же, как на консоли.

В общем, если я хочу, чтобы в программе было два варианта: один для форматирования вывода в HTML, а другой для вывода в виде простого текста, я абстрагирую как можно больше логики в подпрограммы или объекты, которые не выводят, затем есть отдельные процедуры вывода для вариантов. Смотрите, например, http://jcomeau.unternet.net/src/colorforth/as/cf2text,, который связан с cf2html и cf2ansi; одна и та же программа выдает 3 разных выхода в зависимости от того, какая ссылка вызывается. Обратите внимание, что это старый код, и я больше не программирую таким же образом, но, возможно, вы получите от него полезные идеи; возможно нет.

На самом деле, просматривая ссылку, которую я вам дал, я использовал там другую стратегию, используя глобальную, чтобы указать желаемый стиль вывода. У меня нет ни одного недавнего кода с открытым исходным кодом, который мог бы дать вам лучший пример, он принадлежит моим клиентам.

Вот один из способов изменить вывод без изменения операторов печати:

>>> import sys, StringIO
>>> oldout = sys.stdout
>>> sys.stdout = newout = StringIO.StringIO()
>>> for line in 'this', 'that', 'the other': print line
... 
>>> sys.stdout = oldout
>>> print newout.getvalue().replace('\n', '<br />\n')
this<br />
that<br />
the other<br />

Если вы используете этот метод, вы можете изменить тип контента на text / html и использовать любые другие функции HTML. Для более сложных модификаций вывода вы можете использовать подстановку регулярных выражений. И если вы хотите вывод в виде строк, вы можете:

>>> newout.seek(0)
>>> newout.readlines()
['this\n', 'that\n', 'the other\n']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...