微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将.write与外语字符ã,à,ê,ó,...一起使用

如何解决如何将.write与外语字符ã,à,ê,ó,...一起使用

我正在使用Python 3进行一个小型项目,在该项目中,我必须扫描一个充满文件的驱动器,并输出一个.txt文件以及该驱动器中所有文件的路径。问题在于某些文件是巴西葡萄牙语文件,带有“重音字母”,例如“não”,“você”等,而这些特殊字母在最终的.txt中输出错误

代码只是下面几行:

import glob

path = r'path/path'

files = [f for f in glob.glob(path + "**/**",recursive=True)]

with open("file.txt",'w') as output:
    for row in files:
        output.write(str(row.encode('utf-8') )+ '\n')

输出示例

path\folder1\Treino_2.doc
path\folder1\Treino_1.doc
path\folder1\\xc3\x81gua de Produ\xc3\xa7\xc3\xa3o.doc

最后一行显示由于x81gua de Produ\xc3\xa7\xc3\xa3o应该为Régua de Produção

,某些输出错误的。

解决方法

Python文件直接处理Unicode文本(包括巴西带重音符号的字符) 。您需要做的就是在文本模式下使用该文件,这是默认设置,除非您明确要求open()为您提供一个二进制文件。 "w"为您提供了可写的文本文件。

不过,您可能想使用encoding argument for the open() function来明确说明编码:

with open("file.txt","w",encoding="utf-8") as output:
    for row in files:
        output.write(row + "\n")

如果您未明确设置编码,则使用system-specific default is selected。并非所有编码都可以编码所有可能的Unicode代码点。这种情况在Windows上比在其他操作系统上发生的情况要多,在其他操作系统上,默认的ANSI代码页会导致charmap codepage can't encode character错误,但是如果将当前语言环境配置为使用非Unicode编码,则在其他操作系统上也可能发生。

不要编码为字节,然后使用bytes将所得的str()对象再次转换为字符串。这样做只会使字符串表示和转义以及其中的b前缀变得一团糟:

>>> path = r"path\folder1\Água de Produção.doc"
>>> v.encode("utf8")  # bytes are represented with the "b'...'" syntax
b'path\\folder1\\\xc3\x81gua de Produ\xc3\xa7\xc3\xa3o.doc'
>>> str(v.encode("utf8"))  # converting back with `str()` includes that syntax
"b'path\\\\folder1\\\\\\xc3\\x81gua de Produ\\xc3\\xa7\\xc3\\xa3o.doc'"

有关此处发生的情况,请参见What does a b prefix before a python string mean?

,

可能只是想直接将文件名字符串写入文件,而无需首先将它们编码为UTF-8,因为它们已经以这种编码 了。那是:

…
    for row in files:
        output.write(row + '\n')

应该做正确的事。


我说“可能”,是因为在某些操作系统(例如Linux!)中文件名不一定是有效的UTF-8 ,并且将其视为UTF-8会失败。在这种情况下,您唯一的办法是将文件名作为原始字节序列处理-但是,这在您的代码中永远不会发生,因为glob已经返回了字符串而不是字节数组,即Python已经尝试解码字节序列表示文件名为UTF-8。

可以告诉glob通过将globing模式作为字节序列传递来处理任意字节的文件名(即非UTF-8)。在Linux上,以下工作正常:

filename = b'\xbd\xb2=\xbc \xe2\x8c\x98'

with open(filename,'w') as file:
    file.write('hi!\n')

import glob
print(glob.glob(b'*')[0])
# b'\xbd\xb2=\xbc \xe2\x8c\x98'

# BUT:
print(glob.glob('*')[0])
#---------------------------------------------------------------------------
#UnicodeEncodeError                        Traceback (most recent call last)
#<ipython-input-12-2bce790f5243> in <module>
#----> 1 print(glob.glob('*')[0])
#
#UnicodeEncodeError: 'utf-8' codec can't encode characters in position 0-1: surrogates not allowed

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。