[英]How to create a temporary file with Unicode encoding?
当我使用open()
打开文件时,我无法编写unicode字符串。 我了解到我需要使用codecs
并使用Unicode编码打开文件(请参阅http://docs.python.org/howto/unicode.html#reading-and-writing-unicode-data )。
现在我需要创建一些临时文件。 我试图使用tempfile
库,但它没有任何编码选项。 当我尝试使用tempfile
在临时文件中编写任何unicode字符串时,它会失败:
#!/usr/bin/python2.6
# -*- coding: utf-8 -*-
import tempfile
with tempfile.TemporaryFile() as fh:
fh.write(u"Hello World: ä")
fh.seek(0)
for line in fh:
print line
如何在Python中使用Unicode编码创建临时文件?
编辑:
我正在使用Linux,我得到的错误消息是:
Traceback (most recent call last): File "tmp_file.py", line 5, in <module> fh.write(u"Hello World: ä") UnicodeEncodeError: 'ascii' codec can't encode character u'\\xe4' in position 13: ordinal not in range(128)
其他人的答案都是正确的,我只是想澄清一下发生了什么:
文字'foo'
和文字u'foo'
之间的区别在于前者是一串字节而后者是Unicode对象。
首先,要了解Unicode是字符集。 UTF-8是编码。 Unicode对象是前者 - 它是一个Unicode字符串,不一定是UTF-8。 在您的情况下,字符串文字的编码将是UTF-8,因为您在文件的第一行中指定了它。
要从字节字符串中获取Unicode字符串,请调用.encode()
方法:
>>>> u"ひらがな".encode("utf-8") == "ひらがな"
True
类似地,您可以在write
调用中调用string.encode,并获得与删除u
相同的效果。
如果您没有在顶部指定编码,例如,如果您正在从另一个文件中读取Unicode数据,则应在其到达Python字符串之前指定它所处的编码。 这将决定它将如何以字节(即str
类型)表示。
然后,您获得的错误仅仅是因为tempfile
模块需要str
对象。 这并不意味着它不能处理unicode,只是它希望你传入一个字节字符串而不是Unicode对象 - 因为没有你指定编码,它就不知道如何将它写入临时文件。
tempfile.TemporaryFile 在Python 3中有编码选项 :
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import tempfile
with tempfile.TemporaryFile(mode='w+', encoding='utf-8') as fh:
fh.write("Hello World: ä")
fh.seek(0)
for line in fh:
print(line)
请注意,现在您需要指定mode ='w +'而不是默认的二进制模式。 另请注意,Python 3中的字符串文字是隐式Unicode,没有u修饰符。
如果您遇到Python 2.6,临时文件总是二进制文件,您需要在将Unicode字符串写入文件之前对其进行编码:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import tempfile
with tempfile.TemporaryFile() as fh:
fh.write(u"Hello World: ä".encode('utf-8'))
fh.seek(0)
for line in fh:
print line.decode('utf-8')
Unicode指定字符集,而不是编码,因此在任何一种情况下,您都需要一种方法来指定如何编码Unicode字符!
我已经找到了一个解决方案:创建不自动删除临时文件, tempfile
,关闭它,并使用再次打开它codecs
:
#!/usr/bin/python2.6
# -*- coding: utf-8 -*-
import codecs
import os
import tempfile
f = tempfile.NamedTemporaryFile(delete=False)
filename = f.name
f.close()
with codecs.open(filename, 'w+b', encoding='utf-8') as fh:
fh.write(u"Hello World: ä")
fh.seek(0)
for line in fh:
print line
os.unlink(filename)
由于我正在使用应该在Python 2和Python 3中运行的TemporaryFile对象的Python程序,我发现手动编码所有写为UTF-8的字符串并不像其他答案所建议的那样令人满意。
相反,我已经编写了以下小的polyfill(因为我找不到六个类似的东西)来将类似二进制文件的对象包装到类似UTF-8文件的对象中:
from __future__ import unicode_literals
import sys
import codecs
if sys.hexversion < 0x03000000:
def uwriter(fp):
return codecs.getwriter('utf-8')(fp)
else:
def uwriter(fp):
return fp
它以下列方式使用:
# encoding: utf-8
from tempfile import NamedTemporaryFile
with uwriter(NamedTemporaryFile(suffix='.txt', mode='w')) as fp:
fp.write('Hællo wörld!\n')
您正在尝试将unicode对象(u"...")
写入临时文件,您应该使用编码字符串("...")
。 您不必显式传递"encode="
参数,因为您已经在第二行中声明了编码("# -*- coding: utf-8 -*-")
。 只需使用fh.write("ä")
而不是fh.write(u"ä")
,你应该没问题。
放弃你使你的代码适合我:
fh.write("Hello World: ä")
我想这是因为它已经是unicode了。
将sys设置为UTF-8的默认编码将解决编码问题
import sys
reload(sys)
sys.setdefaultencoding('utf-8') #set to utf-8 by default this will solve the errors
import tempfile
with tempfile.TemporaryFile() as fh:
fh.write(u"Hello World: ä")
fh.seek(0)
for line in fh:
print line
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.