为什么我们需要str类型?为什么不只是字节串?

时间:2017-07-22 04:21:19

标签: python python-3.x unicode

Python3具有unicode字符串(str)和bytes。我们已经有了bytestring文字和方法。为什么我们需要两种不同的类型,而不仅仅是各种编码的字节串?

4 个答案:

答案 0 :(得分:9)

你的问题的答案取决于“#34; need。”这个词的含义。"

我们当然不需要str类型,因为我们可以使用我们也可以在没有它的情况下计算的类型来计算所有内容(正如您从措辞良好的问题中得知的那样)。< / p>

但我们也可以理解&#34;需要&#34;从方便的角度来看。拥有sqrt功能真好吗?或logexpsin?你可以自己写这些,但为什么要这么麻烦?标准库设计器将添加有用且方便的功能。

语言本身也是如此。我们是否需要&#34;一会儿循环?不是,我们可以使用尾递归函数。我们是否需要&#34;列表理解? Python中的大量事物并不是原始的。就此而言,我们需要&#34;需要&#34;高级语言。 John von Neumann himself once asked "why would you want more than machine language?"

strbytes相同。类型str虽然不是必需的,但它是一个很好的,省时的,方便的。它为我们提供了一个接口作为一系列字符,这样我们就可以逐个字符地操作文本而不用:

  • 我们必须自己编写所有编码和解码逻辑,或
  • 使用多组迭代器膨胀字符串接口,例如each_byteeach_char

正如您所怀疑的,我们可以有一种类型,它暴露字节序列和字符序列(如Ruby&#39; s String类所做的那样)。 Python设计者希望将这些用法分成两种不同的类型。您可以非常轻松地将一种类型的对象转换为另一种对象。通过有两种类型,他们说关注点(和用法点)的分离比内置类型更少更重要。 Ruby做出了不同的选择。

TL; DR这是语言设计中的偏好问题:通过不同类型而不是同一类型的不同方法分离关注点。

答案 1 :(得分:6)

因为字节不应被视为字符串,并且字符串不应被视为字节。无论这对全新的开发者有多刺耳,Python3都能做到这一点。

在Python 2.6中,如果我从文件中读取数据,并且传递了“r”标志,则默认情况下将在当前语言环境中读取文本,这将是一个字符串,而传递“rb”标志将创建一系列字节。索引数据是完全不同的,采用str的方法可能不确定我是使用字节还是str。这变得更糟,因为对于ASCII数据,这两者通常是同义的,这意味着在遇到非ASCII字符时,在简单测试用例或英语语言环境中工作的代码将失败。

因此有意识地确保字节和字符串不相同:一个是“哑字节”序列,另一个是Unicode字符串,其中数据的最佳编码保留O(1)索引(ASCII,UCS-2或UTF-32,具体取决于使用的数据)。

在Python 2中,Unicode字符串用于消除“哑字节”中的文本歧义,但是str被许多用户视为文本。

或者引用the Benevolent Dictator

  

Python的当前字符串对象被重载。它们用于保存字符序列和字节序列。这种超载的目的会导致混乱和错误。在Python的未来版本中,字符串对象将用于保存字符数据。 bytes对象将履行字节容器的角色。最终,unicode类型将被重命名为str,旧的str类型将被删除。

tl;博士版 迫使bytesstr的分离迫使程序员意识到他们的差异,短期的不满,但更好的代码是长期的。经过多年的经验,这是一种有意识的选择:强迫您立即意识到这种差异将在以后的调试器中节省您的时间。

答案 2 :(得分:2)

具有不同编码的字节字符串彼此不兼容,但在Python 3之前,语言中没有任何内容可以提醒您这一事实。事实证明,混合不同的字符编码在当今世界是一个令人惊讶的常见问题,导致了太多的错误。

此外,使用整个字符通常更容易,而不必担心您只是修改了一个意外将4字节字符呈现为无效序列的字节。

答案 3 :(得分:1)

至少有两个原因:

  1. str类型具有重要属性&#34;一个元素=一个字符&#34;。

  2. str类型不依赖于编码。

  3. 想象一下,如果rword = word[::-1]是带有某些编码的字节串,你将如何实现一个简单的操作,如反转字符串(word)。