Python,编码输出到UTF-8

2024-10-03 21:26:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个定义,它构建了一个由UTF-8编码字符组成的字符串。输出文件使用'w+', "utf-8"参数打开。

然而,当我试图x.write(string)时,我得到了UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 1: ordinal not in range(128)

我想这是因为通常你会做“打印(u'something)”。但我需要用一个变量,用u''。。。

有什么建议吗?

编辑:此处为实际代码:

source = codecs.open("actionbreak/" + target + '.csv','r', "utf-8")
outTarget = codecs.open("actionbreak/" + newTarget, 'w+', "utf-8")
x = str(actionT(splitList[0], splitList[1]))
outTarget.write(x)

基本上,这一切都是为了给我构建大量类似于以下内容的字符串:

[日木曜 Deliverables]= CASE WHEN things = 11 THEN C ELSE 0 END


Tags: 文件字符串in编码参数定义open字符
3条回答

xgord是对的,但是为了进一步的启迪,值得注意\ufeff的确切含义。它被称为BOMbyte order mark,基本上它是对unicode早期的一种回调,当时人们不同意他们希望unicode朝哪个方向发展。现在,所有unicode文档都以\ufeff\uffef作为前缀,这取决于它们决定按哪个顺序排列字节。

如果在第一个位置遇到这些字符的错误,您可以确定问题是您没有尝试将其解码为utf-8,并且文件可能仍然正常。

你在用^{}?Python 2.7的内置open()不支持特定的编码,这意味着您必须手动对非ascii字符串进行编码(正如其他人所指出的那样),但是codecs.open()支持这种编码,并且可能比手动对所有字符串进行编码更容易插入。


由于您实际使用的是codecs.open(),按照您添加的代码执行,并且在自己进行了一些查找之后,我建议尝试打开编码为"utf-8-sig"的输入和/或输出文件,该文件将自动处理UTF-8的BOM(请参阅http://docs.python.org/2/library/codecs.html#encodings-and-unicode,在本节底部附近),我认为这仅对输入文件有意义,但如果这些组合(utf-8-sig/utf-8、utf-8/utf-8-sig、utf-8-sig/utf-8-sig)都不起作用,那么我认为最有可能的情况是,您的输入文件使用BOM以不同的Unicode格式编码,因为Python的默认utf-8编解码器将BOM解释为常规字符,这样输入就不会有问题,但输出可以。


刚刚注意到,但是。。。当您使用codecs.open()时,它需要一个Unicode字符串,而不是编码的字符串;请尝试x = unicode(actionT(splitList[0], splitList[1]))

尝试解码unicode字符串时也可能发生错误(请参见http://wiki.python.org/moin/UnicodeEncodeError),但我认为除非actionT()或列表拆分对unicode字符串执行某些操作,使其被视为非unicode字符串,否则不会发生这种情况。

在Python2.x中有两种类型的字符串:字节字符串和unicode字符串。第一个包含字节,最后一个包含unicode代码点。很容易确定它是什么类型的字符串-unicode字符串以u开头:

# byte string
>>> 'abc'
'abc'

# unicode string:
>>> u'abc абв'
u'abc \u0430\u0431\u0432'

“abc”字符是相同的,因为在ASCII范围内。\u0430是unicode代码点,它超出了ASCII范围。”“代码点”是python内部unicode点的表示,它们不能保存到文件中。需要先将它们编码为字节。这里编码的unicode字符串是什么样子的(当它被编码时,它变成了一个字节字符串):

>>> s = u'abc абв'
>>> s.encode('utf8')
'abc \xd0\xb0\xd0\xb1\xd0\xb2'

此编码字符串现在可以写入文件:

>>> s = u'abc абв'
>>> with open('text.txt', 'w+') as f:
...     f.write(s.encode('utf8'))

现在,重要的是要记住,我们在写入文件时使用了什么编码。因为要能够读取数据,我们需要解码内容。以下是没有解码的数据:

>>> with open('text.txt', 'r') as f:
...     content = f.read()
>>> content
'abc \xd0\xb0\xd0\xb1\xd0\xb2'

你看,我们得到了编码字节,与s.encode('utf8')中的完全相同。要解码,需要提供编码名称:

>>> content.decode('utf8')
u'abc \u0430\u0431\u0432'

解码后,我们得到了带有unicode代码点的unicode字符串。

>>> print content.decode('utf8')
abc абв

相关问题 更多 >