Python 3清理了Python对Unicode字符串的处理。我认为,作为这项工作的一部分,根据Python 3 documentation与Python 2 documentation相比,Python 3中的编解码器变得更加严格。
例如,从概念上将字节流转换为不同形式的字节流的编解码器已被删除:
从概念上将Unicode转换为不同形式的Unicode的编解码器也已被删除(在Python 2中,它实际上介于Unicode和字节流之间,但从概念上讲,它实际上是我认为Unicode的Unicode):
我的主要问题是,Python 3中执行这些删除编解码器的“正确方法”是什么?他们不是严格意义上的编解码器,而是“转换”。但是接口和实现与编解码器非常相似。
我不关心rot_13,但我很想知道实现行结尾样式转换的“最佳方法”(Unix行结尾与Windows行结尾),这应该是一个Unicode-在编码到字节流之前完成的to-Unicode转换,特别是在使用UTF-16时,如this other SO question所述。
答案 0 :(得分:6)
看起来所有这些非编解码器模块都是根据具体情况进行处理的。这是我到目前为止所发现的:
hexlify
和 unhexlify
函数完成3}}模块(一个隐藏的功能)我想这意味着没有用于创建此类字符串/字节数组转换模块的标准框架,但它们是在Python 3中逐个完成的。
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_13
和rot_13
字符串。