在python中读取上标(NG²)和latin-1的编码格式是什么?

时间:2018-05-28 14:34:31

标签: python character-encoding python-2.x

我用python(2.7)脚本从spotify中读取拉丁语播放列表 到目前为止,latin-1工作正常。

但后来我遇到了像NG²这样的名字,这使得它无法正常工作 更多。

这是错误信息:

...
Solo Fue Una Noche;NG²;Comienzos;9;2004 (printed by a print() cmd)
Traceback (most recent call last):
  File "get_playlist-tracks.py", line 110, in <module>
    ndt.write(line+"\n").encode('latin-1')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 21-22: ordinal not in range(128)

我想,我需要拉丁语-1和上标的组合代码 这是否正确,是否有人知道哪一个是正确的?

感谢您的答案!
嗯,这有点复杂:

(同时)我有3台Win10(64位)安装(WinA,WinB,WinC)。
在WinA(最古老的,2011年,从Win7迁移),一切正常(Python3.4)
在winB和WinC(最新的HW,Python3.6)上,curl cmd得到一个退出代码1,没人知道为什么地狱。
由于我想摆脱旧的WinA并继续使用我的python脚本,我只是尝试上的脚本 VMWare Player12中的Fedora20客户。
现在这个上标问题只出现在Fedora系统上(由于卷曲问题,不再对WinA - WinB和WinC不再对我有任何意义)。

我在剧本中使用以下前两行:

#!/usr/bin/python3.3
# -*- coding: utf-8 -*-

只有在我尝试将此行(带上标2)写入文件时才会出现错误:

print (line)         # (works fine!)
ndt.write(line+"\n") # (this one not!)

我尝试使用.decode('utf-8')和.decode('latin-1')写命令 但我总是得到同样的信息......

然后我尝试在python控制台中关注:

>>> line="Solo Fue Una Noche;NG²;Comienzos;9;2004"
>>> playlist_name = '/home/.../Python/PLLs/Sole_01a_tracks.txt'
>>> ndt = open(playlist_name, 'w')
>>> ndt.write(line+"\n").decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'decode'
>>> ndt.write(line+"\n")
40
>>> line
'Solo Fue Una Noche;NG²;Comienzos;9;2004'
>>> playlist_name
'/home/.../Python/PLLs/Sole_01a_tracks.txt'
>>> ndt.write(line)
39

代码

print ("playlist_contents_file:", playlist_name)

打印出:

('playlist_contents_file:', u'/home/.../Python/PLLs/Sole_01a_tracks.txt')

1 个答案:

答案 0 :(得分:1)

问题不是上标2.它是Latin-1字符\xb2,您不需要不同的编码。问题是您对已经是Latin-1的字节字符串调用encode()

首先,要了解encode()采用Unicode字符串并将其转换为将字节值映射到Unicode代码点的某种表示形式。因此要使用它,您必须在Unicode字符串上调用它。如果在普通字符串上调用encode(),Python会先尝试将其强制转换为Unicode。

因为这是Python 2,所以原始字符串(line)是一个字节字符串,除非您告诉它编码是什么,否则无法可靠地强制转换为Unicode。如果不这样做,并选择默认强制,Python会假定为ascii

所以你必须从latin-1 解码以获得Unicode:

>>> line="Solo Fue Una Noche;NG²;Comienzos;9;2004"
>>> line
'Solo Fue Una Noche;NG\xb2;Comienzos;9;2004'
>>> line.decode('latin-1')
u'Solo Fue Una Noche;NG\xb2;Comienzos;9;2004'

在这种情况下,Unicode和Latin-1 发生,以使您的非ascii字符具有相同的8位表示。但这只是一个方便的事故。它可能不同,这就是你必须指定解码的原因。您现在有一个unicode字符串,您可以将'\n'附加到其中:

>>> line.decode('latin-1')+"\n"
u'Solo Fue Una Noche;NG\xb2;Comienzos;9;2004\n'

然后你可以编码这个Unicode字符串回到Latin-1输出:

>>> (line.decode('latin-1')+"\n").encode('latin-1')
'Solo Fue Una Noche;NG\xb2;Comienzos;9;2004\n'

但是对于你正在做的事情,你根本不需要encode()。你说是从Spotify获得Latin-1。您希望输出为Latin-1。因此,您只需将"\n"附加到输入字符串并将其写出来。

>>> line="Solo Fue Una Noche;NG²;Comienzos;9;2004"
>>> line + "\n"
'Solo Fue Una Noche;NG\xb2;Comienzos;9;2004\n'
>>> ndt.write(line+"\n")