Unicode write()-在Python3.x中调用编码字符串
我有一个unicode字符串要写入文件 在Python 2中,我可以写:Unicode write()-在Python3.x中调用编码字符串,unicode,python-3.x,Unicode,Python 3.x,我有一个unicode字符串要写入文件 在Python 2中,我可以写: open('filename', 'w').write(s.encode('utf-8')) 但对于Python3来说,这是失败的。显然,s.encode()返回“bytes”类型的内容,write()函数不接受: TypeError: must be str, not bytes 有人知道如何将上述代码移植到Python3吗 编辑: 感谢所有建议使用二进制模式的人!很遗憾,这会导致\n字符出现问题。是否有任何方法可以
open('filename', 'w').write(s.encode('utf-8'))
但对于Python3来说,这是失败的。显然,s.encode()返回“bytes”类型的内容,write()函数不接受:
TypeError: must be str, not bytes
有人知道如何将上述代码移植到Python3吗
编辑:
感谢所有建议使用二进制模式的人!很遗憾,这会导致\n字符出现问题。是否有任何方法可以实现与Python 2相同的结果(即在UTF-8中编码非ANSI字符,同时保留操作系统特定的格式副本\n)
谢谢 以二进制模式打开文件
open('filename', 'wb').write(s.encode('utf-8'))
以二进制模式打开文件,这是更改方面最小的侵入性方式 另一方面,可以使用open()设置输出文件编码,并完全避免显式字符串编码 您可能需要阅读该函数的手册。您不希望这样手工编码每一条数据!只需将编码作为参数传递给
open
,如下所示:
#!/usr/bin/env python3.2
slist = [
"Ca\N{LATIN SMALL LETTER N WITH TILDE}on City",
"na\N{LATIN SMALL LETTER I WITH DIAERESIS}vet\N{LATIN SMALL LETTER E WITH ACUTE}",
"fa\N{LATIN SMALL LETTER C WITH CEDILLA}ade",
"\N{GREEK SMALL LETTER BETA}-globulin"
]
with open("/tmp/sample.utf8", mode="w", encoding="utf8") as f:
for s in slist:
print(s, file=f)
现在,如果您查看您制作的文件,您将看到它显示:
$ cat /tmp/sample.utf8
Cañon City
naïveté
façade
β-globulin
您可以通过这种方式看到这些是正确的代码点:
$ uniquote -x /tmp/sample.utf
Ca\x{F1}on City
na\x{EF}vet\x{E9}
fa\x{E7}ade
\x{3B2}-globulin
看看这有多容易?让流对象为您处理任何低级编码或解码
摘要:当您正在使用
编码或解码来处理同一编码的同质流时,不要自己调用编码或解码。这对零增益来说太麻烦了。只需一次性使用encoding
参数。在3.2中没有理由不将与
一起使用。另外,f.close()
,而不是f.close
@agf Ug,你是对的。我如何让Python警告我这些愚蠢的错误?在Perl中,我会得到“在void上下文中无用地使用常量”之类的东西。@Lennart:谢谢,但为什么它更好呢?f
?@tchrist:是的,即使您提出错误,f也会关闭。请参阅,您不知道它何时被垃圾回收。你说得对,这对资源管理很重要。这就是为什么您应该将与
一起使用的原因。我选择接受这个答案,因为它帮助我——Python新手——理解有两个有效的选项:使用文本文件,在这种情况下,我需要在打开()时设置编码
,或者使用二进制文件,这与我以前的情况非常相似(但在处理新行时会造成一些困难,但我想只要多做一点努力,我也可以处理它们)。到目前为止,我已经了解并欣赏了Python 3.x区分文本(str
)和(二进制)数据(bytes
)的方法。