覆盖Python的print语句的换行符生成行为

bro*_*hie 8 python printing cpython

我有一堆遗留代码用于编码包含大量打印语句的原始电子邮件,例如

print >>f, "Content-Type: text/plain"
Run Code Online (Sandbox Code Playgroud)

这对电子邮件来说都很好,但我们现在正在利用相同的代码来输出HTTP请求.问题是Python打印语句'\n'在HTTP需要时输出'\r\n'.

看起来像Python(至少2.6.4)PRINT_NEWLINE为print语句生成一个尾随字节代码,实现为

ceval.c:1582: err = PyFile_WriteString("\n", w);
Run Code Online (Sandbox Code Playgroud)

因此,似乎没有简单的方法来覆盖print的默认换行行为.我考虑过以下解决方案

  • 写完输出后,只需做一个.replace('\n', '\r\n').这将干扰使用多部分编码的HTTP消息.
  • 在目标文件对象周围创建一个包装器并代理该.write方法
  • def write(self, data):
        if data == '\n':
            data = '\r\n'
        return self._file.write(data)
    
    Run Code Online (Sandbox Code Playgroud)

  • 写的正则表达式转换print >>f, textf.write(text + line_end)哪里line_end可以'\n''\r\n'.
  • 我认为第三种选择是最合适的.听听你的Pythonic解决问题的方法会很有趣.

    u0b*_*6ae 11

    您应该立即通过定义新的输出函数来解决您的问题.打印一个函数,这会容易得多.

    我建议编写一个新的输出函数,尽可能多地模仿现代打印函数签名(因为重用好的接口很好),例如:

    def output(*items, end="\n", file=sys.stdout):
        pass
    
    Run Code Online (Sandbox Code Playgroud)

    一旦您更换了所有相关的打印件,您就不再有这个问题 - 您可以随时更改功能的行为!这就是为什么print在Python 3中成为一个函数的一个重要原因 - 因为在Python 2.x中,"所有"项目总是经历所有print语句不再灵活的阶段,并且没有简单的方法.

    • +1:永久地打印'打印'.将其视为调试工具,而不是生产代码的实际部分. (8认同)

    mjv*_*mjv 8

    (不确定如何/如果这适合您打算使用的包装,但以防万一...)

    在Python 2.6(以及许多前面的版本)中,您可以通过在print语句的末尾添加逗号来禁止换行,如下所示:

    data = 'some msg\r\n'
    print data,  # note the comma
    
    Run Code Online (Sandbox Code Playgroud)

    然而,使用这种方法的缺点是在Python3中更改了打印语法和行为.