Gre*_*ill 56 python unicode stdout python-3.x
在Python 2中设置默认输出编码是一个众所周知的习惯用法:
sys.stdout = codecs.getwriter("utf-8")(sys.stdout)
Run Code Online (Sandbox Code Playgroud)
这将sys.stdout
对象包装在编解码器编写器中,该编解码器编写器以UTF-8编码输出.
但是,这种技术在Python 3中不起作用,因为sys.stdout.write()
期望a str
,但是编码的结果是bytes
,并且当codecs
尝试将编码的字节写入原始时发生错误sys.stdout
.
在Python 3中执行此操作的正确方法是什么?
Gre*_*ill 38
添加了Python 3.1 io.TextIOBase.detach()
,文档中有一个注释sys.stdout
:
默认情况下,标准流处于文本模式.要将二进制数据写入或读取,请使用基础二进制缓冲区.例如,要写入字节
stdout
,请使用sys.stdout.buffer.write(b'abc')
.io.TextIOBase.detach()
默认情况下,使用流可以成为二进制.这个函数设置stdin
和stdout
二进制:Run Code Online (Sandbox Code Playgroud)def make_streams_binary(): sys.stdin = sys.stdin.detach() sys.stdout = sys.stdout.detach()
因此,Python 3.1及更高版本的相应习语是:
sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
Run Code Online (Sandbox Code Playgroud)
ide*_*n42 29
我在搜索相同错误的解决方案时发现了这个帖子,
对于那些已经建议的解决方案的替代解决方案是在 Python启动之前设置PYTHONIOENCODING
环境变量,供我使用 - 这比在初始化Python 之后交换更少麻烦:sys.stdout
PYTHONIOENCODING=utf-8:surrogateescape python3 somescript.py
Run Code Online (Sandbox Code Playgroud)
具有不必去编辑Python代码的优点.
Jac*_*nor 27
其他答案似乎建议使用codecs
,但open
适合我:
import sys
sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf8', buffering=1)
print("???")
# Also works with other methods of writing to stdout:
sys.stdout.write("???\n")
sys.stdout.buffer.write("???\n".encode())
Run Code Online (Sandbox Code Playgroud)
即使我运行它也可以PYTHONIOENCODING="ascii"
.
sth*_*sth 21
从Python 3.7开始,您可以使用以下命令更改标准流的编码reconfigure()
:
sys.stdout.reconfigure(encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)
您还可以通过添加errors
参数来修改编码错误的处理方式.
bob*_*nce 17
在Python 2中设置默认输出编码是一个众所周知的习惯用法
伊克!这是Python 2中一个众所周知的习惯用法吗?这对我来说似乎是一个危险的错误.
它肯定会弄乱任何尝试将二进制文件写入stdout的脚本(例如,如果你是一个返回图像的CGI脚本,你将需要它).字节和字符是完全不同的动物; 将指定接受字节的接口修补为仅接受字符的接口并不是一个好主意.
CGI和HTTP通常明确地使用字节.您应该只向sys.stdout发送字节.在Python 3中,这意味着使用sys.stdout.buffer.write
直接发送字节.编码页面内容以匹配其charset
参数应在应用程序的更高级别处理(在您返回文本内容而不是二进制文件的情况下).这也意味着print
CGI不再有用.
(为了增加混乱,wsgiref的CGIHandler直到最近才在py3k中被破坏,使得无法以这种方式将WSGI部署到CGI.使用PEP 3333和Python 3.2,这终于可行了.)
pto*_*ato 10
使用detach()
导致解释器在它退出之前尝试关闭stdout时打印警告:
Exception ignored in: <_io.TextIOWrapper mode='w' encoding='UTF-8'>
ValueError: underlying buffer has been detached
Run Code Online (Sandbox Code Playgroud)
相反,这对我来说很好:
default_out = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)
(当然,写作default_out
代替stdout.)
sys.stdout在Python 3中处于文本模式.因此,您直接为其编写unicode,不再需要Python 2的习惯用法.
这在Python 2中会失败:
>>> import sys
>>> sys.stdout.write(u"ûnicöde")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfb' in position 0: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
但是,它在Python 3中只是花花公子:
>>> import sys
>>> sys.stdout.write("Ûnicöde")
Ûnicöde7
Run Code Online (Sandbox Code Playgroud)
现在,如果你的Python不知道你的stdouts编码究竟是什么,那就是一个不同的问题,很可能是在Python的构建中.
归档时间: |
|
查看次数: |
39219 次 |
最近记录: |