【问题标题】:Python CGI: Translate from stdout to html (e.g. replace \n with <BR>)Python CGI:从标准输出转换为 html(例如,将 \n 替换为 <BR>)
【发布时间】:2023-12-10 05:31:01
【问题描述】:

我有一个很棒的命令行程序,可以打印到标准输出。我想让人们通过 CGI 运行它。在 CGI 版本中,我希望有相同的输出(使用 "&lt;BR&gt;" 而不是 "\n")。

我的cgi_main 通过调用my real_main 工作;有很多选择要处理,多次这样做是糟糕的设计。但是由于real_main调用print,我不知道如何将"\n"更改为"&lt;BR&gt;" post hoc。

我可以轻松地将print 的所有实例更改为tempfile,然后在最后转储它,但是对现有命令行版本进行如此多的更改似乎并不优雅。

一种选择是让real_main 调用另一个函数(传递argv);该新函数返回值。然后 real_main 打印这些值。 cgi_main 将调用相同的函数,但打印的值不同。

另一个选择是在我现在使用 print 的任何地方使用类成员/静态函数。这个类可以被告知是否重新格式化。然后在命令行和 CGI​​ 输出之间切换只需要更改 reform 参数。

以下是我认为此类和函数如何工作的示例: 类 cgi_tools: def init(自我,改革=假): self.reform = 改革 def myprint(self, *args): 如果不是 self.reform: 打印(参数) 对于 enumerate(args) 中的 i,x: 如果类型(x)== str: self.myprint(x.replace('\n', '
')), elif type(x) in atom: # 检查 x 是否为原子(即 int、float 等): 打印 x, 别的: self.myprint(x), 如果我!= len(args)-1: 打印 ' ', 打印''

有了这个,我在尝试用 Python 思考所有原子(即不可约对象)时遇到了麻烦。我找不到这个测试的内置函数,我认为自己编写它是一个脆弱的想法。

我尝试使用insepct打印print的源代码,但是我做不到! 打印 sys.out.print:

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

所有这些似乎都是一个经典的 Python CGI 问题,但我找不到很好的解决方案。我知道如何以草率的方式将事物拼凑在一起并得到我想要的,但我希望你能给出关于如何变得优雅的建议。我想成长,我不想再马虎地编程了。

非常感谢您的想法和建议。
-奥利弗

【问题讨论】:

  • Print 的源代码是 C 语言,而不是 python,这就是检查不返回源代码的原因。
  • 为什么不直接发送 text/plain MIME header 而不是 text/html?

标签: python cgi


【解决方案1】:

在 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']

【讨论】:

  • +1 感谢@jcomeau_ictx 并为这个简单的问题道歉。一般来说,如果我想做其他替换(比如列表在 html 中显示为表格等),那么理想的方法是什么?
  • 干杯。有没有办法让我放入 标签并加载它们?
  • 让 CGI 劫持 sys.stdout 是个好主意。