我需要将一些代码从Python2移植到Python3,主要问题似乎是字节类型,因为str(bytes)给我b'%s'
结果,但需要'%s'
,所以我决定覆盖__str__()
字节类的方法,以准确打印我想要的内容。
我尝试使用从字节继承的类修补builtins.bytes
,但这似乎只适用于一个文件而不适用于整个项目,也不会影响字节文字(b''
)。 / p>
如果从py2到py3有任何其他方式(不那么痛苦),那么很高兴看到它们。
使用.decode('UTF-8')
是不可接受的,因为项目超过4k行,并且将解码方法添加到所有必要的位置会导致渐进式错误计数,并且还有一些.decode
个位置在3第二方图书馆。
我试着这样做:
import builtins
class StrBytes(builtins.bytes):
def __str__(self):
return self.decode('UTF-8')
builtins.bytes = StrBytes
然后,如果我使用bytes()
,则会创建StrBytes
对象,而str(bytes())
正是我想要的。这种方式很糟糕,因为它不包括从字节文字构造字节对象:
>>> type(bytes())
<class 'StrBytes'>
>>> type(b'')
<class 'bytes'>
我不确定它是否适用于整个项目,而不仅仅是一个文件。
在我的代码的许多不同的地方,我有类似的东西:
return b''.join(some_extra_values)
keys = [b'1', b'2', b'3'] # actually keys are given from another part of code
for key in keys:
some_dict[key] = some_value
some_dict['1'] # works in py2, not in py3, KeyError
答案 0 :(得分:2)
带有文本的规则是“在输入时解码,在输出上编码”。尽管已经做了很多工作来使编写兼容v2和v3的代码变得更容易,但总会出现一些差异,而且Python 3不再定义unicode
符号的事实是它们。
尝试在Python中修补内置类型并不是一个好主意。因为它们是用C定义的,所以没有有效的方法来修补它们的方法。
一个可能有用的工具是
from __future__ import unicode_literals
当在程序开头插入时,将所有字符串文字解释为Unicode字符串而不是字节串。
调整代码的另一种方法是使用Python 3不实现unicode
名称来驱动特征检测的事实。所以你可以写一下,例如
try:
unicode = unicode # RHS raises NameError on Python 3
except NameError:
unicode = str
然后您可以通过编写
来检查文本类型if type(s) is unicode:
...
并且比较应该在v2和v3中都有效。
如果在输入上正确解码,则不必插入许多调用来解码,并且只需要在必须将字符串传递给某种外部工具时进行编码。