0

我曾经使用 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)

我想,我需要一个 latin-1 和上标的组合代码。
这是正确的吗?有人知道哪个是正确的吗?


感谢您的许多答案!
好吧,它有点复杂:

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

我在脚本中使用以下前 2 行:

#!/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')
4

1 回答 1

1

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

首先,了解它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恰好具有相同的 8 位表示非 ascii 字符。但这只是一个方便的意外。它可能会有所不同,这就是您必须指定解码的原因。您现在有一个 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")
于 2018-05-28T15:04:58.163 回答