104

我是 python3 的新手,来自 python2,我对 unicode 基础知识有点困惑。我读过一些很好的帖子,这让一切变得更加清晰,但是我看到 python 3 上有两种方法可以处理编码和解码,我不确定使用哪一种。

因此,python 3 中的想法是,每个字符串都是 unicode,并且可以以字节编码和存储,或者再次解码回 unicode 字符串。

但是有两种方法可以做到这一点:
u'something'.encode('utf-8')将生成b'something',但也会生成bytes(u'something', 'utf-8')
并且b'bytes'.decode('utf-8')似乎与str(b'bytes', 'utf-8').

现在我的问题是,为什么有两种方法似乎做同样的事情,并且比另一种更好(为什么?)我一直试图在谷歌上找到答案,但没有运气。

>>> original = '27岁少妇生孩子后变老'
>>> type(original)
<class 'str'>
>>> encoded = original.encode('utf-8')
>>> print(encoded)
b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81'
>>> type(encoded)
<class 'bytes'>
>>> encoded2 = bytes(original, 'utf-8')
>>> print(encoded2)
b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81'
>>> type(encoded2)
<class 'bytes'>
>>> print(encoded+encoded2)
b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x8127\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81'
>>> decoded = encoded.decode('utf-8')
>>> print(decoded)
27岁少妇生孩子后变老
>>> decoded2 = str(encoded2, 'utf-8')
>>> print(decoded2)
27岁少妇生孩子后变老
>>> type(decoded)
<class 'str'>
>>> type(decoded2)
<class 'str'>
>>> print(str(b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81', 'utf-8'))
27岁少妇生孩子后变老
>>> print(b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81'.decode('utf-8'))
27岁少妇生孩子后变老
4

3 回答 3

67

两者都不比另一个更好,它们做的事情完全相同。但是,使用.encode()and.decode()是更常见的方法。它还与 Python 2 兼容。

于 2013-01-23T06:09:07.237 回答
18

添加到Lennart Regebro 的回答甚至可以使用第三种方法:

encoded3 = str.encode(original, 'utf-8')
print(encoded3)

无论如何,它实际上与第一种方法完全相同。看起来第二种方法是第三种方法的语法糖。


编程语言是一种正式表达抽象思想的手段,由机器执行。如果一种编程语言包含人们需要的结构,那么它就被认为是好的。Python 是一种混合语言——即比纯OO 或纯过程语言更自然、更通用。有时函数比对象方法更合适,有时反之亦然。这取决于已解决问题的心理图景。

无论如何,问题中提到的功能可能是语言实现/设计的副产品。在我看来,这是一个很好的例子,它展示了技术上相同事物的替代思维。

换句话说,调用对象方法意味着以“让对象给我想要的结果”的方式思考。调用函数作为替代方法意味着“让外部代码处理传递的参数并提取想要的值”

第一种方法强调对象自己完成任务的能力,第二种方法强调单独算法提取数据的能力。有时,单独的代码可能非常特殊,以至于将其作为通用方法添加到对象的类中是不明智的。

于 2013-01-23T07:59:29.743 回答
12

要添加到前面的答案,甚至还有第四种方法可以使用

import codecs
encoded4 = codecs.encode(original, 'utf-8')
print(encoded4)
于 2014-05-09T06:36:31.357 回答