tri*_*nth 14 python unicode encoding utf-8
我有一个子进程命令输出一些字符,如'\ xf1'.我正在尝试将其解码为utf8但我收到错误.
s = '\xf1'
s.decode('utf-8')
Run Code Online (Sandbox Code Playgroud)
以上抛出:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf1 in position 0: unexpected end of data
Run Code Online (Sandbox Code Playgroud)
当我使用'latin-1'但是不应该使用utf8时它可以正常工作吗?我的理解是latin1是utf8的子集.
我在这里错过了什么吗?
编辑:
print s # ñ
repr(s) # returns "'\\xa9'"
Run Code Online (Sandbox Code Playgroud)
您将Unicode与UTF-8混淆了.Latin-1是Unicode的子集,但它不是UTF-8的子集.避免像瘟疫一样考虑个别代码单元. 只需使用代码点.不要考虑UTF-8.请考虑使用Unicode.这是你感到困惑的地方.
在Python中使用Unicode非常简单.它特别适用于Python 3和广泛构建,这是我使用Python的唯一方法,但是如果你小心坚持使用UTF-8,你仍然可以在一个狭窄的版本中使用传统的Python 2.
为此,请始终将源代码编码和输出编码正确地转换为UTF-8.现在停止考虑UTF-anything并在整个Python程序中仅使用UTF-8文字,逻辑代码点编号或符号字符名称.
这是包含行号的源代码:
% cat -n /tmp/py
1 #!/usr/bin/env python3.2
2 # -*- coding: UTF-8 -*-
3
4 from __future__ import unicode_literals
5 from __future__ import print_function
6
7 import sys
8 import os
9 import re
10
11 if not (("PYTHONIOENCODING" in os.environ)
12 and
13 re.search("^utf-?8$", os.environ["PYTHONIOENCODING"], re.I)):
14 sys.stderr.write(sys.argv[0] + ": Please set your PYTHONIOENCODING envariable to utf8\n")
15 sys.exit(1)
16
17 print('1a: el ni\xF1o')
18 print('2a: el nin\u0303o')
19
20 print('1a: el niño')
21 print('2b: el niño')
22
23 print('1c: el ni\N{LATIN SMALL LETTER N WITH TILDE}o')
24 print('2c: el nin\N{COMBINING TILDE}o')
Run Code Online (Sandbox Code Playgroud)
以下是使用符号单引号的非ASCII字符的打印函数\x{?}:
% grep -n ^print /tmp/py | uniquote -x
17:print('1a: el ni\xF1o')
18:print('2a: el nin\u0303o')
20:print('1b: el ni\x{F1}o')
21:print('2b: el nin\x{303}o')
23:print('1c: el ni\N{LATIN SMALL LETTER N WITH TILDE}o')
24:print('2c: el nin\N{COMBINING TILDE}o')
Run Code Online (Sandbox Code Playgroud)
以下是该程序的示例运行,其中显示了执行此操作的三种不同方式(a,b和c):第一个在源代码中设置为文字(这将受到StackOverflow的NFC转换的影响,因此无法信任! !)和后两组分别使用数字Unicode代码点 和符号Unicode字符名称,再次单引号,以便您可以看到实际情况:
% python /tmp/py
1a: el niño
2a: el niño
1b: el niño
2b: el niño
1c: el niño
2c: el niño
% python /tmp/py | uniquote -x
1a: el ni\x{F1}o
2a: el nin\x{303}o
1b: el ni\x{F1}o
2b: el nin\x{303}o
1c: el ni\x{F1}o
2c: el nin\x{303}o
% python /tmp/py | uniquote -v
1a: el ni\N{LATIN SMALL LETTER N WITH TILDE}o
2a: el nin\N{COMBINING TILDE}o
1b: el ni\N{LATIN SMALL LETTER N WITH TILDE}o
2b: el nin\N{COMBINING TILDE}o
1c: el ni\N{LATIN SMALL LETTER N WITH TILDE}o
2c: el nin\N{COMBINING TILDE}o
Run Code Online (Sandbox Code Playgroud)
我真的不喜欢看二进制文件,但这里看起来像二进制字节:
% python /tmp/py | uniquote -b
1a: el ni\xC3\xB1o
2a: el nin\xCC\x83o
1b: el ni\xC3\xB1o
2b: el nin\xCC\x83o
1c: el ni\xC3\xB1o
2c: el nin\xCC\x83o
Run Code Online (Sandbox Code Playgroud)
即使您使用UTF-8源,您也应该只考虑和使用逻辑Unicode代码点编号(或符号命名字符),而不是构成UTF-8串行表示形式的单个8位代码单元(或者UTF-16).很少需要代码单元而不是代码点,它只会让您感到困惑.
如果你使用广泛的Python3,你将获得更可靠的行为,而不是那些选择的替代品,但这是UTF-32问题,而不是UTF-8问题.UTF-32和UTF-8都很容易使用,如果您只是顺其自然.