Python 3中的流/字符串/字节数组转换

时间:2009-07-29 01:04:56

标签: encoding python-3.x

Python 3清理了Python对Unicode字符串的处理。我认为,作为这项工作的一部分,根据Python 3 documentationPython 2 documentation相比,Python 3中的编解码器变得更加严格。

例如,从概念上将字节流转换为不同形式的字节流的编解码器已被删除:

  • base64_codec
  • bz2_codec
  • hex_codec

从概念上将Unicode转换为不同形式的Unicode的编解码器也已被删除(在Python 2中,它实际上介于Unicode和字节流之间,但从概念上讲,它实际上是我认为Unicode的Unicode):

  • rot_13

我的主要问题是,Python 3中执行这些删除编解码器的“正确方法”是什么?他们不是严格意义上的编解码器,而是“转换”。但是接口和实现与编解码器非常相似。

我不关心rot_13,但我很想知道实现行结尾样式转换的“最佳方法”(Unix行结尾与Windows行结尾),这应该是一个Unicode-在编码到字节流之前完成的to-Unicode转换,特别是在使用UTF-16时,如this other SO question所述。

2 个答案:

答案 0 :(得分:6)

看起来所有这些非编解码器模块都是根据具体情况进行处理的。这是我到目前为止所发现的:

    现在可以通过base64模块获取
  • base64
  • bz2 现在可以使用bz2模块
  • 完成
  • 十六进制字符串编码/解码可以通过{{{strong> hexlify unhexlify 函数完成3}}模块(一个隐藏的功能)

我想这意味着没有用于创建此类字符串/字节数组转换模块的标准框架,但它们是在Python 3中逐个完成的。

Python 3.2的更新

binascii提醒我这些编解码器回归Python 3.2。

引用评论:

  

因为这些是“文字到文字”或   但是,“二进制到二进制”转换,   in中的encode()/ decode()方法   Python 3.x不支持这种风格   用法 - 它只是Python 2.x.   功能)。

     

编解码器本身又回到了3.2,   但你需要通过编解码器   模块API,以便使用它们 - 它们   不能通过对象方法获得   简写。

查看comment on a blog post "Compressing text using Python’s unicode support"

来自Python 3 docs for codecs — Binary Transforms

  

您是否知道Python 2提供了一些编解码器来进行有趣的转换,例如Caeser旋转(即rot13)?因此,您可以执行以下操作:

>>> 'foo'.encode('rot-13')
'sbb'
     

这在Python 3中不起作用,因为即使某些str-to-str编解码器如rot-13仍然存在,str.encode()接口也要求编解码器返回一个bytes对象。为了在Python 2和Python 3中使用str-to-str编解码器,你必须使用低级API,直接获取和调用编解码器:

>>> from codecs import getencoder
>>> encoder = getencoder('rot-13')
>>> rot13string = encoder(mystring)[0]
     

由于编解码器API,您必须从编码器的返回值中获取第0个元素。有点难看,但它适用于两个版本的Python。

答案 1 :(得分:2)

您对线路结束转换的具体需求是什么?如果它只是用于写入文件或文件对象,则可以指定要与open()一起使用的行结束格式,并且\n将在您写入文件时自动转换为该格式。不可否认,这仅适用于以文本形式打开的文件,而不是数据。 (您还可以指定在将文本写入文件时使用的编码,这有时很有用。)

http://docs.python.org/3.1/library/functions.html#open

要使用常规字符串进行转换,您只需执行yourstring = yourstring.replace('\n', '\r\n')即可从Linux样式转换为Windows样式,而yourstring = yourstring.replace('\r\n', '\n')则可以从Windows样式转换为Linux样式。你可能已经知道了这一点,而且它可能不是你想要的。 (并且,实际上,如果您正在写入文本文件,如果启用了通用换行模式,则无论如何它都应该在Windows系统上将\n转换为\r\n。这是默认设置。)

同样,如果你想在各种Unicode映射之间进行转换(假设你正在使用字节序列,因为Python内部使用的字符串实际上并没有设置为任何特定类型的Unicode),它只是一个使用bytes.decode()bytearray.decode()解码字节序列然后使用str.encode()进行编码的问题。对于从UTF-8到UTF-16的转换:

newstring = yourbytes.decode('utf-8')
yourbytes = newstring.encode('utf-16')

当以这种方式完成时,在两种Unicode格式之间没有正确转换换行符时应该没有任何问题。

还有str.translate()str.maketrans(),但我不确定这些是否有用:

http://docs.python.org/3.1/library/stdtypes.html#str.translate
http://docs.python.org/3.1/library/stdtypes.html#str.maketrans

另外,rot_13可以这样实现:

import string
rot_13 = str.maketrans({x: chr((ord(x) - ord('A') + 13) % 26 + ord('A') if x.isupper() else ((ord(x) - ord('a') + 13) % 26 + ord('a'))) for x in string.ascii_letters})

# Using hard-coded values:

rot_13 = str.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')

无论哪种方式,使用S.translate(rot_13)都会导致普通字符串变为普通字符串rot_13rot_13字符串。