代码之家  ›  专栏  ›  技术社区  ›  Paul

难以处理sys.stdin中的unicode

  •  0
  • Paul  · 技术社区  · 7 年前

    现在这让我有点发疯。从我最近的研究中可以清楚地看出,Unicode是一个复杂的主题。但这是我不知道如何解决的行为。

    如果我从磁盘读取一个包含非ASCII字符的文件,并将其写回到文件中,那么一切都将按计划工作。但是,当我从sys.stdin读取同一个文件时,ID不起作用,而且非ASCII字符编码不正确。示例代码如下:

    # -*- coding: utf-8 -*-
    import sys
    
    with open("testinput.txt", "r") as ifile:
        lines = ifile.read()
    
    with open("testout1.txt", "w") as ofile:
        for line in lines:
            ofile.write(line)
    
    with open("testout2.txt", "w") as ofile:
        for line in sys.stdin:
            ofile.write(line)
    

    输入文件 testinput.txt 是这样的:

    を
    Sōten_Kōro
    

    当我从命令行运行脚本时 cat testinput.txt | python test.py 我分别得到以下输出:

    testout1.txt :

    圣尼 S_

    testout2.txt :

    ??? S??ten_K??ro

    任何关于如何解决这一问题的想法都会很有帮助。谢谢。保罗。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Giacomo Catenazzi    7 年前

    原因是你抄近路,这是不应该走的。

    您应该总是定义一个编码。因此,当您读取文件时,应该指定您正在读取UTF-8,或者每当读取时都要指定。或者只需显式地说明您正在读取二进制文件。

    在您的例子中,Python解释器在读取文件时将使用UTF-8作为标准编码,因为这是Linux和MacOS中的默认值。

    但是,当您从标准输入中读取时,缺省值是由区域设置编码或环境变量定义的。

    我指的是 How to change the stdin encoding on python 如何解决。这个答案只是为了解释原因。

        2
  •  0
  •   Paul    7 年前

    谢谢你的指点。我已经基于@giacomocatenazzi的答案和参考实现了以下功能:

    # -*- coding: utf-8 -*-
    import sys
    import codecs
    
    with open("testinput.txt", "r") as ifile:
        lines = ifile.read()
    
    with open("testout1.txt", "w") as ofile:
        for line in lines:
            ofile.write(line)
    
    UTF8Reader = codecs.getreader('utf-8')
    sys.stdin = UTF8Reader(sys.stdin)
    with open("testout2.txt", "w") as ofile:
        for line in sys.stdin:
            ofile.write(line.encode('utf-8'))
    

    但是我不知道为什么在使用后需要重新编码 codecs.getreader ?

    保罗