2017-01-04 113 views
0

我是Python 3的新手,似乎无法完全掌握unicode和字符编码。当字节对象显然只包含字符时,将Python 3字节对象转换为字符串

我正在处理另一个工具的输出,它将html页面的内容作为字节对象返回。我们使用的其他工具需要此输出为字节类型,但是,我想将字节输出转换为字符串,以便解析和比较其他字符串。对于我感兴趣的情况,打印输出字节对象只显示字符并且不显示\ x或\ u二进制文件。我对如何最好地做到这一点以及为什么创建所需输出的方法实际上有效而感到困惑。

我已经在其他地方读过.decode()应该在这个上下文中使用,这确实有效,但我不明白为什么我解码已经是字符的对象。据我了解,解码是为二进制数,例如:

>>> b'\x41'.decode('utf-8') 
'A' 

在我的理解,我真正想要做的是告诉Python的是一个已经被标记为一个字节类型对象的对象实际上是一个STR目的。只需在bytes对象上使用str()函数即可实现此目标,但会添加“b”前缀并在字符串周围添加引号。

这里有两种解决方案我的工作:

>>> str(b'htmltext') 
"b'htmltext'" 

>>> b'htmltext'.decode('utf-8') 
'htmltext' 

从本质上讲,这两种方案似乎达到什么我正在寻找,但解码()似乎很明显更清洁,并从什么我读过,推荐的方法。我想知道为什么解码()的作品,鉴于此,显然,我不会将二进制数字转换为字符。此外,除了输出中没有吸引力的“b”和引号外,是否还有其他原因,str()在这里不是有效的解决方案?

+0

一旦你理解*为什么* Python3将字符串和二进制数据分为两种不同的类型,这将更容易回答。请参阅http://eli.thegreenplace.net/2012/01/30/the-bytesstr-dichotomy-in-python-3 – turbulencetoo

+1

* Everything *是二进制数据。 –

+0

认为计算机中的每一件事物都有二进制表示是很自然的,但在Python中它不是那样的 - 太糟糕了!特别是,字符串是没有编码的unicode对象,编码是从unicode对象到字节对象的映射。这是查看字符串,字节对象及其关系的一种方式,但我看不到获得的结果。 –

回答

4

请勿混淆bytes对象的开发人员友好型表示与其中包含的数据。你有两种方式的二进制数据。

开发商表示,很容易让你看到什么是展示什么,只是碰巧是一个有效的ASCII码点为ASCII字符,而不是\xhh转义码包含。以这种方式阅读以ASCII编码的文本更容易,而世界上的许多文本恰好是ASCII编码的。

你有困难时,当数据不是然而ASCII范围:

>>> 'Åæøéï'.encode('utf8') 
b'\xc3\x85\xc3\xa6\xc3\xb8\xc3\xa9\xc3\xaf' 

这是一个UTF-8字节序列编码的文本与口音。以上可能有点做作,但大多数非英文文本将包含的一些非ASCII文本。即使是英文文本可以包含长划线或花哨的报价,以及该b'...'字节版本是几乎没有的正确解码文本版本的可读性:

>>> '“Kragerø” is a town in Norway – in the province of Vestfold'.encode('utf8') 
b'\xe2\x80\x9cKrager\xc3\xb8\xe2\x80\x9d is a town in Norway \xe2\x80\x93 in the province of Vestfold' 

注意,b'....'输出使用repr() function结果在bytes对象;即调用object.__repr__() method,它具有为您生成适合开发人员的字符串的显式功能。 bytes对象上没有专用object.__str__() method,但调用了__repr__方法,即使使用str()函数。将bytes转换为字符串的正确方法是解码(使用正确的数据编解码器)。

当然,当你有二进制数据代表别的东西,就像图像数据一样,然后把它保存为bytes。没有文字解码。

+0

这个解释非常有帮助。这填补了我在其他地方令我困扰的理解上的空白。谢谢! – QuintenG